Victor Guyot
Victor Guyot

Reputation: 33

Translating C++ DLL into C# - How to translate a struct included in a struct

I have to translate a C++ DLL into C# to use it in a project. Here is the part that causes me trouble. This is the C++ code of the header of the DLL :

struct initiate_rb
{
    unsigned char Rem_Add;
    unsigned char Features_Supported_1_m;
    struct add_addr_param Add_Addr_Param;
};

struct add_addr_param
{
    unsigned char D_Type;
    unsigned char D_Len;
    struct
    {
        unsigned char Network_Address[6];
        unsigned short MAC_Address_Len;
        unsigned char * MAC_Address;
    } S_Addr;
};

I am not sure how to handle this in C#. Here is what I have achieved so far :

[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct initiate_rb
{
    public byte Rem_Add;
    public byte Features_Supported_1_m;
    public add_addr_param Add_Addr_Param;
}


[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct add_addr_param
{
    public byte D_Type;
    public byte D_Len;

    [StructLayout(LayoutKind.Sequential)]
    public struct S_Addr
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] Network_Address;
        public ushort MAC_Address_Len;
        public byte* MAC_Address;
    };
}

I used Pack = 1 because in my DLL header file there is the line #pragma pack (1)

The problem is, this doesn't work when I have to use this struct. It returns me an error code. So first, concerning this struct translation, am I doing it right ?

Thanks for helping.

Upvotes: 0

Views: 180

Answers (2)

Victor Guyot
Victor Guyot

Reputation: 33

In fact I resolved this problem. The problem was that I was using a constructor for my initiate_rb struct

unsafe struct initiate_rb
{
    public byte Rem_Add;
    public byte Features_Supported_1_m;
    public add_addr_param Add_Addr_Param;

    public initiate_rb(int networkAddressLength) : this()
    {
        Rem_Add = (byte)0;
        Features_Supported_1_m = (byte)0;
        add_addr_param = new Add_Add_Param(networkAddressLength);
    }
}

and this constructor for add_addr_param :

[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct add_addr_param
{
    public byte D_Type;
    public byte D_Len;

    [StructLayout(LayoutKind.Sequential)]
    public struct S_Addr
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] Network_Address;
        public ushort MAC_Address_Len;
        public byte* MAC_Address;
    };

    public add_addr_param(int networkAddressLength) : this()
    {
        D_Type = (byte)0;
        D_Len = (byte)0;

        S_Addr.Network_Address = new byte[6]; //problem with this line
    }
}

This was the problem. Since I remove this line, the code was operating correctly. In fact I didn't need constructors since all parameters have to be set to 0.

Thanks for helping!

Upvotes: 1

t3chb0t
t3chb0t

Reputation: 18744

I'm not sure about the attributes but I believe the second struct shoudn't be nested in C# because the one in C++ defines a variable of the struct's type just after the closing parentheses.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct dpc2_add_addr_param
{
    public byte D_Type;
    public byte D_Len;
    public S_Addr S_Addr;
}

[StructLayout(LayoutKind.Sequential)]    
public struct S_Addr
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] Network_Address;
    public ushort MAC_Address_Len;
    public byte* MAC_Address;
};

Upvotes: 1

Related Questions