转换c++;将struct转换为c#并使用它? 我有一个C++结构如下:< /P> struct Vehicle { u32 something; Info *info; u8 something2[ 0x14 ]; Vector3f location; Template* data; }; struct Info { u32 speed; std::string name; BuffCollection** buffCollection; void* sectionPtr; }; struct Template { u32 templateID; };

转换c++;将struct转换为c#并使用它? 我有一个C++结构如下:< /P> struct Vehicle { u32 something; Info *info; u8 something2[ 0x14 ]; Vector3f location; Template* data; }; struct Info { u32 speed; std::string name; BuffCollection** buffCollection; void* sectionPtr; }; struct Template { u32 templateID; };,c#,c++,struct,C#,C++,Struct,,我理解了u32、u8等的含义,或者我想我是这样理解的 然后我试着用它制作自己的C#struct: [StructLayout(LayoutKind.Sequential)] public struct Vehicle { public uint Something; public Info Info; public byte Something2; public Vector3f Location; public Template Data; } [S

,我理解了u32、u8等的含义,或者我想我是这样理解的

然后我试着用它制作自己的C#struct:

[StructLayout(LayoutKind.Sequential)]
public struct Vehicle
{
    public uint Something;
    public Info Info;
    public byte Something2;
    public Vector3f Location;
    public Template Data;
}

[StructLayout(LayoutKind.Sequential)]
public struct Info
{
    public uint Speed;
    public string Name;
    public byte[] BuffCollection;
    public IntPtr SectionPointer;
}

[StructLayout(LayoutKind.Sequential)]
public struct Template
{
    public uint TemplateId;
}

public struct Vector3f
{
    public float X, Y, Z;
    public Vector3f(float x, float y, float z)
    {
        X = x;
        Y = y;
        Z = z;
    }
}
但是,当我尝试阅读车辆时:

[DllImport("Core.dll")]
static extern Vehicle GetVehicle();

static void Main() 
{
    var vehicle = GetVehicle();
    Console.WriteLine(vehicle.Info.Name);
    Console.ReadKey();
}
我得到以下错误:

System.Runtime.InteropServices.MarshalDirectiveException: Method's type signature is not PInvoke compatible
从我对它的研究来看,它让我相信我的结构转换是错误的

  • 我转换的结构有什么问题?
关于结构:

  • Vehicle.Info
    是一个指针,因此需要将其声明为
    IntPtr Info
    ,然后使用
    Marshal.PtrToStructure/Marshal.StructureToPtr
    在托管代码中读取/写入其值

  • Vehicle.something2
    是一个字节数组,而不是一个字节,因此您需要这样声明:

    [Marshallas(UnmanagedType.ByValArray,SizeConst=20)]
    字节[]something2=新字节[20]

  • 车辆.数据
    -参见#1,相同问题

  • >代码>信息.Name < /COD> > .NET不为STD::String提供编组,所以您要么需要编写自己的封送器(见此:),要么将类型更改为C++库中的char *。
  • Info.BuffCollection
    也应该是IntPtr或BuffCollection[](取决于BuffCollection类型-您的问题中没有提供)
  • 关于
    GetVehicle()的签名和调用方法:

    该方法很可能返回指向结构的指针,而不是结构本身(只是推测,请仔细检查)。如果是,您需要将其声明为

    static extern IntPtr GetVehicle();
    
    然后使用
    Marshal.PtrToStructure
    将其转换为您的结构,如下所示:

    var vehiclePtr=GetVehicle();
    var vehicle = (Vehicle)Marshal.PtrToStructure(vehiclePtr, typeof(Vehicle));
    

    我的问题错了吗?我看到没有任何信息的投票结果为什么。。。是因为在底部我得了3分吗?如果是这样,我可以删除其他2个问题并使它们成为一个新问题。函数的C++签名是什么?@ TeoDooSoCasigigiaNaKiS<代码> Extn“C”代码>不确定这是否是您要查找的内容,但除了结构之外,我只知道这些,因为我无法访问DLL源代码。请注意
    车辆
    中的
    内容2
    ,因为它是一个数组。@Caramiriel所以它应该是
    字节[]
    ?嗨,丹尼斯,谢谢你的详细回答,你能给出一个我将如何在函数上使用Marshal.PtrToStructure的示例吗?当然,将示例添加到我的响应中可以使用
    [marshals(UnmanagedType.Struct)]公共信息而不是
    IntPtr数据
    ?我不这么认为。Struct表示变量包含结构,但在您的示例中,它是指向结构的指针(Info*Info)。您可以尝试使用UnmanagedType.LPStruct,但我从未尝试过。ptr结构是IMHO更“传统”的方式