平台调用、布尔值和字符串

发布于 2024-09-26 20:46:40 字数 789 浏览 2 评论 0原文

假设 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# 字符串拥有,而不是复制,就像我想的那样预计,最终 C# 代码会释放 dll 返回的内存。我发现这一点是因为程序崩溃了,但后来我将返回类型更改为 sbyte* 并使用已经执行复制的指针手动初始化字符串。所以第二个问题是: 2.1:有没有更好的方法来防止编组字符串拥有指针。 2.2:什么鬼?!为什么 C# 这样做?我的意思是,一个明显的情况是 dll func 返回一个文字,而 C# 尝试删除它......

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

suppose a dll contains the following functions

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

My first naive approach to use these functions from C# was as follows:

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

The first surprise was that C++ bool doesn't convert into C# bool (strange runtime behavior, but no crashes, though). So I had to change bool to byte and convert from one to another by hand. So, first question is, is there any better way to marshal bool (note that this is bool, not BOOL)

The second surprise was that the raw string returned by the dll function was OWNED by the C# string, not copied, as I would expect, and eventually the C# code frees the memory returned by the dll. I found this out because the program crashed, but then I changed the return type to sbyte* and manually initialized the string with that pointer which already does the copy. So the second question is: 2.1: Is there any better way to prevent the marshalled string from owning the pointer. 2.2: WTF?! Why does C# do that? I mean, an obvious case is when the dll func returns a literal, and C# tries to delete it...

Thanks in advance, and hopefully my questions aren't vague or incomprehensible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Oo萌小芽oO 2024-10-03 20:46:40
[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();
[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();
哎呦我呸! 2024-10-03 20:46:40

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

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

By default .NET marshals between C++ BOOL (4 bytes) and .NET bool type automatically. For the C++ bool (single byte) type you need to specify how to marshal:

[DllImport("MyDll.dll")]
internal static extern void f([MarshalAs(UnmanagedType.I1)] bool x);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文