c# - 对于此 C 代码,哪种编码方式是正确的?

标签 c# c marshalling

我有两种不同的将 C 代码编码(marshal)到 C# 的实现。

首先C代码是:

int GetVersion(char * pVer, size_t * piSize);

我在 C# 中的第一次尝试(我没有显示 DllImport 部分):

static extern int GetVersion( byte[] ver, ref UIntPtr size );

以及 C# 中的其他尝试:

static extern int GetVersion([MarshalAs(UnmanagedType.LPStr)] StringBuilder ver, ref ulong size);

我从 net 中的不同示例中了解到这些。但我无法断定哪个是正确的。

最佳答案

简而言之:我们总能做到这一点

static extern int GetVersion(IntPtr ver, ref UIntPtr size );

我永远不会写这个,因为我不喜欢它为 A->W 转换生成的内容:

static extern int GetVersion([MarshalAs(UnmanagedType.LPStr)] StringBuilder ver, ref UIntPtr size);

此外,如果这是一个真正的计数字符串,P/Invoke 代码将不起作用,因为它希望在结束后有一个 0。

我通常会写

static extern int GetVersion( byte[] ver, ref UIntPtr size );

您必须首先在其中创建最大大小的 ver。然后,您可以使用 System.Text.Encoding 中的内容将 ver 转换为字符串。 GetVersion() 几乎肯定会返回一个常量,因此您可以硬编码正确的编码(无论如何可能是 ASCII)。

您很有可能缺少 [DllImport(..., CallingConvention=CallingConvention.Cdecl)] 导致内存损坏,但我实际上无法判断。

错误:不要将 ulong 用于 size_tsize_t 在所有支持的平台上都是 UIntPtr


评论建议完全不同的签名 GetDevInfo(int Index, DevInfo * pdevInfo); 这是完全不同的事情,显然有一个最佳选择:

const int IDLength = 100;
[StructLayout(LayoutKind.Sequential)]
struct DeviceInfo {
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = IDLength)]
   byte[] ID;
}

static extern /* I don't know what's here because missing from comment */
    GetDevInfo(int index, ref strcut DeviceInfo info);

string GetInfo(int index)
{
    var info = new DeviceInfo();
    info.ID = new byte[IDLength];
    GetDevInfo(info.ID);
    return System.Text.Encoding.ASCII.GetString(info.ID, 0, strlen(info.ID));
}

int strlen(byte[] bytes)
{
    int i;
    for (i = 0; i < bytes.Length && bytes[i] != 0; i++)
        ;
    return i;
}
````

关于c# - 对于此 C 代码,哪种编码方式是正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70646780/

相关文章:

c# - 用货币符号解析值

c - 由于指针 (C),流水线理念不起作用

c++ - 如何将 s.st_dev 转换为/sys/block/<name>

c# - 在不装箱的情况下将字节数组复制到通用类型

java - 将 Spring-ws webservicetemplate 请求以 XML 格式保存到 DB

c# - 在 try,catch block 之外运行代码是否有任何性能优势?

c# - linq中varchar字段的和,如何进行转换

c# - C# 中的线程和静态方法

c - 如何测量 C 程序中的 scanf 时间?

python - 如何将 Python 模块(来自 PyObject*)转换并保存为二进制数据以便以后使用?