为什么这个Explicit P/Invoke不起作用?

Kum*_*mar 1 c# c++ pinvoke visual-studio-2008 visual-c++

以下.net到本机C代码不起作用,任何想法

extern "C" {
   TRADITIONALDLL_API int TestStrRef( __inout char* c)    {
   int rc = strlen(c);
   std::cout << "the input to TestStrRef is: >>" << c << "<<" ;
   c = "This is from the C code ";
   return rc;
   }
 }

 [DllImport("MyDll.dll", SetLastError = true)]
 static extern int TestStrRef([MarshalAs(UnmanagedType.LPStr)] ref string s);
 String abc = "InOut string";
 TestStrRef(ref abc);
Run Code Online (Sandbox Code Playgroud)

此时Console.WriteLine(abc)应该打印"这是来自C代码"但是没有,任何关于什么错误的想法?

仅供参考 - 我有另一个不使用ref类型字符串的测试函数,它工作得很好

Tar*_*han 5

你的代码也在C方面错了.__inout注释只告诉编译器你可以改变"c"参数指向的缓冲区.但是指针本身位于堆栈中,如果修改了"c"参数,则不会返回调用者.您的声明可能如下:

extern "C" {
   TRADITIONALDLL_API int TestStrRef( __inout char** c)    {
   int rc = strlen(*c);
   std::cout << "the input to TestStrRef is: >>" << *c << "<<" ;
   *c = "This is from the C code ";
   return rc;
   }
 }
Run Code Online (Sandbox Code Playgroud)

和C#方面:

[DllImport("MyDll.dll", SetLastError = true)]
static extern int TestStrRef(ref IntPtr c);

{
    String abc = "InOut string";
    IntPtr ptrOrig = Marshal.StringToHGlobalAnsi(abc)        
    IntPtr ptr = ptrOrig; // Because IntPtr is structure, ptr contains copy of ptrOrig
    int len = TestStrRef(ref ptr);
    Marshal.FreeHGlobal(ptrOrig); // You need to free memory located to abc' native copy
    string newAbc = Marshal.PtrToStringAnsi(ptr); 
    // You cannot free memory pointed by ptr, because it pointed to literal string located in dll code.
}
Run Code Online (Sandbox Code Playgroud)