简体   繁体   中英

passing a c++ struct to a c# application

I have the following structure in my cpp file:

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

I have a method that gets an index # and returns the correct structure:

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

this method is exposed so I can use this method in my c# application and I keep getting an error:

marshal directive exception.

my c# code:

[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;
}

What am I missing?

From the msdn documentation page it says :

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.

So judging by your structure

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

You should define your C# structure like such :

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

LPStr is used when you have "a pointer to a null-terminated array of ANSI characters" but what you have instead is a fixed length array.

Finally Solved. The issue was that from the cpp structure I return a pointer to the structure:

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

and in my c# application:

    [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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM