我试图制作绝对最简单的最小例子,说明如何在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.这似乎是处理最琐碎的事情,但我完全坚持下去.当我尝试使用"添加"功能进行类似的实验,这个功能需要两个双打并且返回一个双重而没有问题.
您不能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);