平台调用,bool和字符串

时间:2010-10-10 20:45:50

标签: c# c++ c interop marshalling

假设一个dll包含以下函数

extern "C" __declspec(dllexport) void f(bool x)
{
   //do something
}
extern "C" __declspec(dllexport) const char* g()
{
   //do something else
}

我在C#中使用这些函数的第一个天真的方法如下:

[DllImport("MyDll.dll")]
internal static extern void f(bool x);
[DllImport("MyDll.dll")]
internal static extern string g();

第一个惊喜是C ++ bool没有转换成C#bool(奇怪的运行时行为,但没有崩溃)。所以我不得不将bool更改为byte并手动将其从一个转换为另一个。所以,第一个问题是,有没有更好的方法来编组bool(注意这是bool,而不是BOOL)

第二个惊喜是dll函数返回的原始字符串是C#字符串的OWNED,没有像我期望的那样复制,最终C#代码释放了dll返回的内存。我找到了这个,因为程序崩溃,但后来我将返回类型更改为sbyte *并使用已经执行复制的指针手动初始化字符串。所以第二个问题是:2.1:有没有更好的方法来阻止编组的字符串拥有指针。 2.2:WTF?!为什么C#会这样做?我的意思是,一个明显的例子是当dll func返回一个文字时,C#试图删除它......

提前致谢,希望我的问题不含糊或不可理解。

2 个答案:

答案 0 :(得分:5)

默认情况下,.NET会自动在C ++ BOOL(4字节)和.NET bool类型之间进行编组。对于C ++ bool(单字节)类型,您需要指定如何编组:

[DllImport("MyDll.dll")]
internal static extern void f([MarshalAs(UnmanagedType.I1)] bool x);

答案 1 :(得分:5)

[DllImport("MyDll.dll")]
internal static extern void f( [MarshalAs(UnmanagedType.I1)] bool x );
[DllImport("MyDll.dll")]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string g();