调用C DLL函数来封装类型定义的char中的字符串

时间:2013-02-17 21:04:38

标签: c# c pinvoke dllimport

这是我第一次尝试为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#中正确编组呢?

1 个答案:

答案 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?这对于这个无参数函数没什么影响,但不久之后你就会传递参数,你需要知道。