【发布时间】: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 位)。我相信在这种情况下编组并不简单。您最好根据自己的目的使用不同的类型(string、StringBuilder或byte[])。 -
我打算用它来计算 OpenCL 中的数组。有与 C# 的 char 相同的 cl_half 类型。我无法将其指针复制到 GPU。实际上我需要 char 数组的指针来开始在 opencl 的一个命令中复制它的所有字节。
-
尝试将此添加到 DllImportAttribute:
CharSet = CharSet.Ansi -
@cubrr 不错,但没用
-
@cubrr CharSet.Unicode 工作