调用一个C DLL函数来封送来自类型定义字符的字符串
本文关键字:类型 定义 字符串 字符 函数 一个 DLL 调用 | 更新日期: 2023-09-27 17:59:42
这是我第一次尝试为C库创建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#中正确地整理它?
如果返回为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
?这个无参数函数没有什么区别,但不久之后你就会传递参数,你需要知道。