c# - 调用 C DLL 函数以从类型定义的 char 编码字符串

标签 c# c pinvoke dllimport

这是我第一次尝试为 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 的调用都会导致崩溃,也不异常(exception)。我感觉它是返回类型,但是如何在 C# 中正确地编码(marshal)它?

最佳答案

如果您以字符串形式返回,则编码器将在返回的指针上调用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?对于这个无参数函数来说没有什么区别,但不久你就会传递参数,你需要知道。

关于c# - 调用 C DLL 函数以从类型定义的 char 编码字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14926036/

相关文章:

c# - 如何在 C# 中读取 Win32 WM_MOVE lParam x,y 坐标?

c# - .NET Core 中的自定义授权属性

c# - 在C#中访问带有 "no name"(空格)的目录/文件夹

c# - 构建 vSphere DLL 失败并出现 CS8078 : An expression is too long or complex to compile

c - 将 const char** 传递给函数 - 如何构建 char**?

c - 支持具有全局数据的插件 DLL 的多个实例

c# - 如何将结构传递给 C++ 函数并通过一些修改返回相同的结构?

c# - 如何更改服务总线队列的属性?

c - 倒数比向上数快吗?

c - 修改通过引用传递的变量与从函数返回它