gpt4 book ai didi

c# - PInvoke 的字符类型**

转载 作者:行者123 更新时间:2023-11-30 22:07:03 26 4
gpt4 key购买 nike

考虑以下 C 函数:

void get_lib_version(const char **ver_string);

如何使用 PInvoke 正确编码它?文档说它返回一个指向静态字符串的指针。我认为这会做到这一点:

[DllImport(DllPath, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_lib_version(StringBuilder version);

但我得到的只是乱码。

最佳答案

该函数返回一个全新的 C 字符串。 pinvoke 编码器始终确保再次释放存储 native 代码返回的字符串所需的内存。这不会有好结果,当然这个函数的调用者不应该释放它。 const 关键字强烈暗示 native 代码将返回指向未在堆上分配的字符串文字的指针。尝试释放这样的指针会使您的程序在更高版本的 Windows 上崩溃,这种版本具有严格的堆实现(在 XP 之后)。

你必须帮助阻止编码器这样做。这要求您将参数声明为原始指针,而不是字符串:

  [DllImport(DllPath, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_lib_version(out IntPtr version);

而且您必须采取额外的步骤将指针转换为字符串:

  public string GetLibraryVersion() {
IntPtr strptr;
get_lib_version(out strptr);
return Marshal.PtrToStringAnsi(strptr);
}

编写一个小测试程序来验证这个假设。调用 GetLibraryVersion() 十亿次。如果内存使用量没有激增,那么你就很好。

关于c# - PInvoke 的字符类型**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23219625/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com