这是我第一次尝试为C lib创建C#包装器。 SDK是第三方,不受我控制:
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#中正确编组呢?
答案 0 :(得分:2)
如果您返回string
,则编组将在返回的指针上调用CoTaskMemFree
。我希望你正在发生的事情是你的代码失败的原因。看看那个API似乎很有可能返回的指针指向DLL中的字符串文字,当然不是用CoTaskMemAlloc
分配的东西。
因此,您需要将其作为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
是什么。它是stdcall
还是cdecl
?这对于这个无参数函数没什么影响,但不久之后你就会传递参数,你需要知道。