API 的问题,其中 char* return 在 P/invoke 中被 IntPtr 捕获

Issue with API with char* return being caught by IntPtr in P/invoke

我正在尝试 P/Invoke C++ API 返回一个 char*,它是 C# 中的一个字符串。我知道这应该被 IntPtr 捕获,然后像这样使用 Marshaler 将指针转换为字符串,

C++ API

char* WINAPI MY_API(const char *basebuf, char *strbuf)
{
  return targetfunction(basebuf, strbuf);
}

C#P/Invoke

[DllImport("myDll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
internal static extern IntPtr MY_API([MarshalAs(UnmanagedType.LPStr)] string basebuf,
                                     [MarshalAs(UnmanagedType.LPArray), Out] byte[] strbuf);

C# 包装器

public string MY_API_WRAPPER(string basebuf, out string strbuf)
{
     byte[] strbufTemp = new byte[256]; 

     IntPtr ret = MY_API(basebuf, strbufTemp); 
     string retstr = Marshal.PtrToStringAnsi(ret); 
     strbuf = MyDataConverter.ByteToString(strbufTemp);  

     return retstr;
}

输出参数字符串正常。但返回的字符串(从 IntPtr 转换而来)是垃圾。

我可以修改 C++ API 以将 char* 分配给任务内存,然后在 C# Wrapper 中释放它,但是更改本机代码不是一个选项。如果在没有包装器的情况下使用 API,它也有内存泄漏的风险。

我想知道当 API 调用结束时指针发生了什么?

感谢 David,我能够解决我的问题。由于函数的return值是指向basebuf参数的指针,所以在函数returns.

时获取垃圾值

basebuf 应该是 IntPtr 而不是 IntPtr 的字符串 return 才能在调用后获得正确的值。所以应该是这样P/Invoked。

C#P/Invoke

[DllImport("myDll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
internal static extern IntPtr MY_API(IntPtr basebuf,
                                     [MarshalAs(UnmanagedType.LPArray), Out] byte[] strbuf);

C# 包装器

public string MY_API_WRAPPER(string basebuf, out string strbuf)
{
     byte[] strbufTemp = new byte[256]; 
     IntPtr basebufPtr = Marshal.StringtoHGlobalAnsi(basebuf)
     IntPtr ret = MY_API(basebufPtr , strbufTemp); 
     string retstr = Marshal.PtrToStringAnsi(ret); 
     strbuf = MyDataConverter.ByteToString(strbufTemp);  
     Marshal.FreeHGlobal(basebufPtr);
     return retstr;
}