将 C++ 结构传递给 C# 应用程序

passing a c++ struct to a c# application

我的 cpp 文件中有以下结构:

struct EntityData
{
    char globalId[512];
    int mySpeed;
    double x;
    double y;
    double z;
    double h;
    double p;
    double r;
};

我有一个获取索引 # 和 returns 正确结构的方法:

extern "C" { __declspec(dllexport) getDataStruct(int index)

公开了此方法,因此我可以在我的 C# 应用程序中使用此方法,但我一直收到错误消息:

marshal directive exception.

我的 C# 代码:

[DllImport("my64.dll")]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern EntityDataRx getDataStruct(int index);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EntityDataRx
{
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 512)]
    StringBuilder globalId;
    int mySpeed;
    double x;
    double y;
    double z;
    double h;
    double p;
    double r;
}

我错过了什么?

msdn documentation page 它说:

The ByValTStr type is used for inline, fixed-length character arrays that appear within a structure. Other types apply to string references contained within structures that contain pointers to strings.

所以从你的结构来看

struct EntityData
{
    char globalId[512];
    // ...
}

您应该像这样定义您的 C# 结构:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EntityDataRx
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
    char[] globalId;
    // ...
}

当你有 "a pointer to a null-terminated array of ANSI characters" 时使用

LPStr 但你拥有的是一个固定长度的数组。

终于解决了。 问题是从 cpp 结构我 return 指向结构的指针:

struct EntityData
{
    char globalId[512];
    int mySpeed;
    double x;
    double y;
    double z;
    double h;
    double p;
    double r;
};

在我的 C# 应用程序中:

    [DllImport("listenHLA1516e_64.dll")]
    //[return: MarshalAs(UnmanagedType.Struct)] **cancelled not necessary**
    public static extern IntPtr getDataStruct(int index);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct EntityDataRx
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
        char[] globalId;
        int mySpeed;
        double x;
        double y;
        double z;
        double h;
        double p;
        double r;
    }

    IntPtr a = getDataStruct(i);
    EntityDataRx ent = (EntityDataRx)Marshal.PtrToStructure(a, typeof(EntityDataRx));