【问题标题】:Why this Explicit P/Invoke does not work?为什么这个显式 P/Invoke 不起作用?
【发布时间】:2010-06-10 14:25:25
【问题描述】:

以下 .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);

此时,Console.WriteLine(abc) 应该打印“This is from the C code”,但没有,有什么想法吗?

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

【问题讨论】:

  • 首先让它在 C 中工作。
  • Native C - 它是 C .net - 不知道 :(

标签: c# c++ visual-studio-2008 visual-c++ pinvoke


【解决方案1】:

您的代码在 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;
   }
 }

还有 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.
}

【讨论】:

    【解决方案2】:

    这对你有用吗?基本上只需在 DllImport 语句中添加 CallingConvention = CallingConvention.Cdecl 即可。您可能还想指定CharSet(例如:CharSet:=CharSet.Unicode)

     [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
     static extern int TestStrRef([MarshalAs(UnmanagedType.LPStr)] ref string s);
    

    【讨论】:

    • 为什么调用约定很重要?调用方法已经为 OP 工作了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    相关资源
    最近更新 更多