我正在使用PInvoke、反向PInvoke方案,如Thottam R. Sriram所描述的那样。http://blogs.msdn.com/b/thottams/archive/2007/06/02/pinvoke-reverse-pinvoke-and-stdcall-cdecl.aspx
一切似乎都很顺利,除了从C++传递字符串到C#的问题。
(在Sriram中,字符串是在C#中构建并未经修改地通过C++传递的,因此避免了这个问题。)
C#代码如下:
(在Sriram中,字符串是在C#中构建并未经修改地通过C++传递的,因此避免了这个问题。)
C#代码如下:
class Program
{
public delegate void callback(string str);
public static void callee(string str)
{
System.Console.WriteLine("Managed: " + str);
}
static void Main(string[] args)
{
gpscom_start(new callback(Program.callee));
Console.WriteLine("NMEA COM Monitor is running");
System.Threading.Thread.Sleep(50000);
}
[DllImport("gpscomdll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void gpscom_start(callback call);
}
这段 C++ 代码看起来像这样:
extern "C" dllapi void __stdcall gpscom_start(void (__stdcall *callback) (BSTR str))
{
BSTR bstr = SysAllocString(L"starting monitor");
(*callback)(bstr);
SysFreeString(bstr);
运行时,一切看起来都很好,除了回调字符串
Managed: m
看起来是由ANSI例程打印出的UNICODE字符串,但C#字符串肯定是Unicode的吧?
谢谢!
public delegate void callback([MarshalAs(UnmanagedType.BStr)] string str);
如果需要,导入System.Runtime.InteropServices命名空间。 这告诉运行时未管理的代码希望这是BSTR(或者可能是BSTR *,我不是interop专家) - Gideon Engelberth