英文:
Problem in converting Packed C structs to go structure by cgo
问题
当我们使用#pragma pack (push, 1)
对C结构进行打包,并通过cgo转换为Go结构时,转换后的Go结构中有一些字段丢失。
我正在使用的Go版本是:1.16.6 Windows/386
例如,我的C结构如下所示:
#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)
转换为Go后,结构如下所示:
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
}
正如我们所看到的,一些字段没有正确转换;相反,它们有“_”。
如果没有#pragma pack
行,转换是正确的;然而,我需要进行打包,因为我使用的库对发送到我们应用程序的结构要求进行打包。
有没有解决这个问题的方法?
英文:
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?
答案1
得分: 1
我实际上在这个问题上写了一篇完整的博客文章:https://medium.com/@liamkelly17/working-with-packed-c-structs-in-cgo-224a0a3b708b
简要说明如下:
- 查看Go的GitHub维基页面,在cgo部分他们明确提到cgo不会对结构体进行打包
- 你可以很容易地自己打包结构体,类似于将结构体编码为JSON然后发送。通过使用
binary
包,你可以迭代结构体成员并将它们放入[]byte
中。然后可以将[]byte
作为打包的结构体传递给C函数(从C函数接收打包的结构体则相反操作)。
英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论