2

这是我第一次尝试为 C 库创建 C# 包装器。SDK 是第 3 方,不受我控制:

sdk_defines.h

#ifndef SDK_CHAR_T
#define SDK_CHAR_T
typedef char sdk_char_t;
#endif /* SDK_CHAR_T */

#ifndef SDK_CSTR_T
#define SDK_CSTR_T
typedef const sdk_char_t*  sdk_cstr_t;
#endif /* SDK_CSTR_T */

sdk.h

sdk_cstr_t SDK_API
sdk_get_version(void);

我的 C# 包装器:

[DllImport("sdk.dll", CharSet = CharSet.Ansi)]
private static extern string sdk_get_version();

对 sdk_get_version 的任何调用都会导致崩溃,没有例外。我感觉它是返回类型,但是如何在 C# 中正确编组它?

4

1 回答 1

2

如果您返回 as string,则编组器将调用CoTaskMemFree返回的指针。我希望这就是发生在您身上的事情,也是您的代码失败的原因。看看那个 API,返回的指针很可能指向 DLL 中的字符串文字,当然不是用CoTaskMemAlloc.

因此,您需要将其作为 an 返回,IntPtr然后使用Marshal.PtrToStringAnsi.

所以你需要这样的:

[DllImport("sdk.dll")]
private static extern IntPtr sdk_get_version();

....

IntPtr ptr = sdk_get_version();
string version = Marshal.PtrToStringAnsi(ptr);

在你走得更远之前,你需要弄清楚SDK_API是什么。是stdcallcdecl?这个无参数函数没有任何区别,但不久你就会传递参数,你需要知道。

于 2013-02-17T21:14:34.370 回答