简体   繁体   中英

Problem in converting Packed C structs to go structure by cgo

When we use #pragma pack (push, 1) to pack the C structure and convert to go structure by cgo, some of the fields are missing in the converted Go structure.

I am using Go version: 1.16.6 Windows/386

For example, my C struct is like this:

#pragma pack (push, 1)
typedef struct _sample_struct
{
    USHORT                   usNo;
    DWORD                    ft;
    DWORD                    fit;
    CHAR                     cID[5];
    CHAR                     cCID[3];
    ULONG                    ulVal;
    ULONG                    ulIn;
    ULONG                    ulCnt;
    ULONG                    ulMax;
    USHORT                   usStat;
    BOOL                     bAlk;
    LPSTRUCT2                lpNNL;
    USHORT                   usNPCU;
    LPSTRUCT4 *              lppP;
    LPSTR                    lpBuff;
    LPUSHORT                 lpusIDS;
    WORD                     usType;
    LPSTR                    lpszCUName;
    ULONG                    ulICnt;
    ULONG                    ulDCnt;
    ULONG                    ulPCnt;
    ULONG                    ulRCnt;
    ULONG                    ulRJCnt;
    ULONG                    ulMin;
} SAMPLESTRUCT, *LPSAMPLESTRUCT;
#pragma pack (pop)

Converted to Go, the structure looks like below:

type _Ctype_struct__sample_struct struct {
    usNo        _Ctype_USHORT
    _       [8]byte
    cID     [5]_Ctype_CHAR
    cCID        [3]_Ctype_CHAR
    _       [16]byte
    usStat      _Ctype_USHORT
    bAlk        _Ctype_BOOL
    lpNNL       _Ctype_LPSTRUCT2
    usNPCU      _Ctype_USHORT
    _       [12]byte
    usType      _Ctype_WORD
    lpszCUName  _Ctype_LPSTR
    ulICnt      _Ctype_ULONG
    ulDCnt      _Ctype_ULONG
    ulPCnt      _Ctype_ULONG
    ulRCnt      _Ctype_ULONG
    ulRJCnt     _Ctype_ULONG
    ulMin       _Ctype_ULONG
}

As we can see, some of the fields are not converted properly; instead, it has "_".**

Conversion is correct without the #pragma pack lines; however, I need packing in place because the library that I use imposes packing for the structures that are sent to our application.

Is there any solution to this problem?

I actually wrote a whole blog post on this: https://medium.com/@liamkelly17/working-with-packed-c-structs-in-cgo-224a0a3b708b

The quick notes are:

  • Look at the Go wiki page on GitHub, in the cgo section they explicitly mention cgo will not pack structs
  • You can very easily pack the structs yourself in a similar to encoding a struct to JSON before sending it. By using the binary package you can iterate through struct members and place them into a []byte . The []byte can then be passed as a packed struct to C functions. (do the opposite to receive packed structs from c functions)

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