将 C# char 数组传递给 C++ 与字节数组不同

Posted

技术标签:

【中文标题】将 C# char 数组传递给 C++ 与字节数组不同【英文标题】:Passing C# char array to C++ not same as byte array 【发布时间】:2017-10-27 07:44:23 【问题描述】:

在 C++ 中,

__declspec(dllexport)
    void charArrayTest(void * ptr)

    char*c = (char*)ptr;
    c[0] = 97;
    c[1] = 0;
    c[2] = 97;
    c[3] = 0;

这适用于 C# 字节数组:

[DllImport("KutuphaneCL", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void charArrayTest(byte[] arr);


byte[] tst = new byte[20];
charArrayTest(tst);
Console.WriteLine(tst[0]);
Console.WriteLine(tst[1]);
Console.WriteLine(tst[2]);
Console.WriteLine(tst[3]);
Console.WriteLine(tst[4]);
Console.WriteLine(tst[5]);

输出:

97 0 97 0 0 0

但是当我从 C# 端尝试 char 数组时,

[DllImport("KutuphaneCL", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void charArrayTest(char[] arr);


//simpleCharSingleGPU();
char[] tst = new char[20];
charArrayTest(tst);
Console.WriteLine((int)tst[0]);
Console.WriteLine((int)tst[1]);
Console.WriteLine((int)tst[2]);
Console.WriteLine((int)tst[3]);
Console.WriteLine((int)tst[4]);
Console.WriteLine((int)tst[5]);

它输出零。我期望非零值,因为每个 char 的较低或较高部分在 C++ 中被更改(除非 char 数组未作为原始数组传递)

为什么 C# 不能像字节数组一样传递字符数组(我知道 char 在内存中是 2 个字节,但这与“我无法在 C++ 中更改它”的情况有什么关系? )

使用带有最新更新的 Visual Studio 2015 社区版。两边都是为 x64 编译的。

还有一些奇怪的事情,例如 Marshal.SizeOf(tst[0].GetType()) 在 C# 中返回“1”而 sizeof(char) 返回“2”(不安全的上下文)。

【问题讨论】:

如您所说,在 C# 中,char 是一个 unicode 字符(16 位)。我相信在这种情况下编组并不简单。您最好根据自己的目的使用不同的类型(stringStringBuilderbyte[])。 我打算用它来计算 OpenCL 中的数组。有与 C# 的 char 相同的 cl_half 类型。我无法将其指针复制到 GPU。实际上我需要 char 数组的指针来开始在 opencl 的一个命令中复制它的所有字节。 尝试将此添加到 DllImportAttribute:CharSet = CharSet.Ansi @cubrr 不错,但没用 @cubrr CharSet.Unicode 工作 【参考方案1】:

你可以通过这种方式将字符串转换为字节数组

byte[] bytes = Encoding.ASCII.GetBytes(somestring);

并将其传递给 c++ 函数

【讨论】:

那么你的意思是没有复制就没有办法了吗? 不知道因为在c#中char是两个字节,c++是一个字节,某处肯定有转换。 @huseyintugrulbuyukisik 你总是可以将值保存为一个字节 将其作为char[] 传递给C++ 函数不起作用,但字节工作浮点工作双工作,所有其他原始工作。也许 char 不是原始的? char 是原始的,但在 c++ 和 c# 中是不同的。 c++ 本身支持 8 位的 ANSI 编码,所以 char 有 8 位。 c# 本机支持 UTF-16,因此 char 有 16 位。这就是原因。

以上是关于将 C# char 数组传递给 C++ 与字节数组不同的主要内容,如果未能解决你的问题,请参考以下文章

将 C# 3D 数组作为 1D 字节数组传递给 C++ 库

将 c++ dll 的 char 指针数组传递给 c# 字符串

将字节数组从 c++ 传递到 c# 程序集都有哪些不同的方法?

使用 Dllimport 将一个非常大的字符串作为字节数组从 C++ 传递到 C#

将字节数组从 c++ 传递到 c#(单声道)

将 char 数组值从 C++ 传递到 C# 应用程序