gpt4 book ai didi

c# - 在 C++/C# 之间的结构内传递字符串/数组

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:08:43 24 4
gpt4 key购买 nike

我正在将结构从 C# 传递到 C++。

C#代码:

[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct Data
{
[MarshalAs(UnmanagedType.U4)]
public int number;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public int[] array;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
public string buffer;
}

C++代码:

struct Data
{
public:
int number;
int array[5];
char buffer[512];
//char *buffer;
};

上述方法效果很好。但是相反,如果我使用指针来处理 C++ 中的数据,我会收到如下错误:

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory

struct Data
{
public:
int number;
int *array;
char *buffer;
};

为什么我不能在这里处理指针?通过指针处理这种情况是否有利?

最佳答案

问题在于您的数据在内存中的表示方式。

假设您有一个 c# 结构的实例,它可以编码到非托管代码甚至文件。

[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct Data
{
[MarshalAs(UnmanagedType.U4)]
public int number = 5;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public int[] array = {0, 1, 2, 3, 4};

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]

public string buffer = "Happy new Year";
}

据此,你的内存布局将是这样的(在十六进制 View 中):

05 00 00 00 00 00 00 00
01 00 00 00 02 00 00 00
03 00 00 00 04 00 00 00
00 48 00 61 00 70 00 70
00 79 00 20 00 6E 00 65
00 77 00 20 00 59 00 65
00 61 00 72

这里我们有前四个字节“05 00 00 00”,这意味着“number”变量在内存中的数字“5”。 (请注意,这些字节的顺序是相反的,因为 Intel 体系结构是 LittleEndian,有关详细信息,请参阅 Endiannes)

然后我们有接下来的五个整数 "00 00 00 00"= 0, "01 00 00 00"= 1, "02 00 00 00"= 2, "03 00 00 00"= 3, "04 00 00 00"= 4 用于名为“array”的数组。

字符串“buffer”表示如下:

"00 48" = H
"00 61" = a
"00 70" = p
"00 70" = p
"00 79" = y
"00 20" = <space>
"00 6E" = n
"00 65" = e
"00 77" = w
"00 20" = <space>
"00 59" = Y
"00 65" = e
"00 61" = a
"00 72" = r

.NET 总是使用 Unicode 来存储它的字符串变量。每个 Unicode 字符都有其双字节表示。

现在,对于这个 C++ 结构

struct Data
{
public:
int number;
int array[5];
char buffer[512];
//char *buffer;
};

sizeof(int) 是 4。因此变量“number”=“05 00 00 00”的内存内容是数字 5。数组[0],数组1 ,array[2],array[3],array[4] 布局在内存块上 "00 00 00 00"= 0, "01 00 00 00"= 1, "02 00 00 00"= 2, "03 00 00 00"= 3,"04 00 00 00"= 4。其他一切都保留给 buffer[512] 变量。但在c++中,sizeof(char) == 1。char数据类型通常用于表示旧的ASCII风格的文本,采用单字节编码。您应该改用 wchar_t,它非常适合 Unicode 编码。

现在让我们来看看

struct Data
{
public:
int number;
int *array;
char *buffer;
};

此结构将投影到与上述相同的内存布局上。如果你在 32 位环境下运行 (win32)“数组”指针的内容将为“00 00 00 00”(指针为 4 个字节)“缓冲区”指针将为“01 00 00 00”。

如果你在64位环境下运行(win64)“数组”指针的内容将为“00 00 00 00 01 00 00 00”(指针为 8 个字节),缓冲区指针将为“02 00 00 00 03 00 00 00”。

这些是某种无效指针,指向谁知道在哪里。这就是为什么当您尝试取消引用它们时会遇到访问冲突。

关于c# - 在 C++/C# 之间的结构内传递字符串/数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34395409/

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