将字符串从C#传递到C ++ DLL并返回-最小的例子

我试图使如何在C#中的C ++ DLL之间传递字符串的绝对最简单的最小示例。


我的C ++看起来像这样:


using std::string;


extern "C" {

    string concat(string a, string b){

        return a + b;

    }

}

像这样的标题


using std::string;


extern "C" {

    // Returns a + b

    __declspec(dllexport) string concat(string a, string b);

}

我的C#是


[DllImport("*****.dll", CallingConvention = CallingConvention.Cdecl)]

    static extern string concat(string a, string b);

}

我用以下方式调用它:Console.WriteLine(concat(“ a”,“ b”));


但这给出了System.AccessViolationException。看来这似乎是最琐碎的事情,但是我完全坚持了下来。当我尝试使用“添加”功能进行类似的实验时,该函数进行了两次加倍操作并返回了一次加倍操作,我没有遇到任何问题。


神不在的星期二
浏览 764回答 2
2回答

守着星空守着你

您不能std::string跨互操作边界传递C ++ 。您不能在C#代码中创建其中之一。因此,您的代码将永远无法工作。您需要在互操作边界使用互操作友好类型。例如,以null终止的字符数组。当您在同一模块中分配和取消分配内存时,这种方法效果很好。因此,将数据从C#传递到C ++时非常简单。C ++void foo(const char *str){    // do something with str}C#[DllImport("...", CallingConvention = CallingConvention.Cdecl)static extern void foo(string str);....foo("bar");在另一个方向上,您通常希望调用方分配缓冲区,被调用方可以在其中写入以下内容:C ++void foo(char *str, int len){    // write no more than len characters into str}C#[DllImport("...", CallingConvention = CallingConvention.Cdecl)static extern void foo(StringBuilder str, int len);....StringBuilder sb = new StringBuilder(10);foo(sb, sb.Capacity);

元芳怎么了

这是我最简单的方法-传入一个字符串,然后使用一个lambda来获取响应C# [DllImport(@"MyDLL.dll", EntryPoint ="Foo", CallingConvention = CallingConvention.StdCall)] public static extern void Foo(string str, ResponseDelegate response); ... Foo("Input", s => {    // response is returned in s - do what you want with it });C ++ typedef void(_stdcall *LPEXTFUNCRESPOND) (LPCSTR s); extern "C" {     __declspec(dllexport) void __stdcall Foo(const char *str, LPEXTFUNCRESPOND respond)      {         // Input is in str         // Put your response in respond()         respond("HELLO");     } } 
打开App,查看更多内容
随时随地看视频慕课网APP