编组嵌套结构

本文关键字:结构 嵌套 | 更新日期: 2023-09-27 17:59:39

我有两个C++结构,如下所示。当从C#调用DLL方法时,我必须获得结构。

例如,让我们在C++代码中将它们定义如下:

struct A
{
    int count;
    struct B;
}
struct B
{
    char* id;
    char* name;
}

C++代码返回以下方法

A* GetData();

我需要从C#调用的一个方法具有以下签名:

IntPtr GetData ();

此方法提供指向结构A的指针,填充结构A中的计数、结构B中的id和名称。

在C#中,我将这些结构定义为类:

[StructLayout(LayoutKind.Sequential)]
class A
{
    public int count;
    public IntPtr B;
}
[StructLayout(LayoutKind.Sequential)]
class B
{
    public string id;
    public string name;
}

我已经创建了一个从C#调用的C++dll。

当我尝试从嵌套结构(A->B->id)读取数据时,我得到了读取冲突错误(AccessViolationException)

如何封送嵌套结构,以便能够在C#方法中读取它?

我的C#代码如下

[DllImport("Win32Project.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern IntPtr GetData();
A setting = new A();
setting.B = new IntPtr();
IntPtr deviceSettingptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(A)));
IntPtr settingsInfoptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(B)));
Marshal.StructureToPtr(setting, deviceSettingptr, false);
Marshal.StructureToPtr(setting.B, settingsInfoptr, true);
setting.B= settingsInfoptr;
deviceSettingptr = GetData();
setting = (A)Marshal.PtrToStructure(deviceSettingptr, typeof(A));
B info = (B)Marshal.PtrToStructure(setting.B, typeof(B));
Console.WriteLine(string.Format("Setting count={0}", setting.count));
Console.WriteLine(string.Format("Setting id={0}, Setting name={1}", info.id, info.name)); 

如何访问具有id和name的结构体B的成员?

编组嵌套结构

您发布的代码看起来有点奇怪。线前的一切

deviceSettingptr = GetData();

似乎无关紧要。您没有显示GetData()的作用,但这个方法似乎是返回一个指向结构的指针。因此,首先读取结构(可能是A):

deviceSettingptr = GetData();
setting = (A)Marshal.PtrToStructure(deviceSettingptr, typeof(A));

(此时,您之前对变量setting所做的任何操作都将过时)。

现在您想要(可能)从setting.B:指向的内存中读取B类型的结构

B info = (B)Marshal.PtrToStructure(setting.B, typeof(B));

在您的代码中,您使用了未正确设置的settingsInfoptr

现在您可以访问info:的属性idname

Console.WriteLine(string.Format("Setting count={0}", setting.count));
Console.WriteLine(string.Format("Setting id={0}, Setting name={1}", info.id, info.name)); 

请注意,可能有人应该再次释放GetData()分配的内存。