将Packed C结构转换为Go结构体时出现问题,通过cgo。

huangapple go评论116阅读模式
英文:

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结构如下所示:

  1. #pragma pack (push, 1)
  2. typedef struct _sample_struct
  3. {
  4. USHORT usNo;
  5. DWORD ft;
  6. DWORD fit;
  7. CHAR cID[5];
  8. CHAR cCID[3];
  9. ULONG ulVal;
  10. ULONG ulIn;
  11. ULONG ulCnt;
  12. ULONG ulMax;
  13. USHORT usStat;
  14. BOOL bAlk;
  15. LPSTRUCT2 lpNNL;
  16. USHORT usNPCU;
  17. LPSTRUCT4 * lppP;
  18. LPSTR lpBuff;
  19. LPUSHORT lpusIDS;
  20. WORD usType;
  21. LPSTR lpszCUName;
  22. ULONG ulICnt;
  23. ULONG ulDCnt;
  24. ULONG ulPCnt;
  25. ULONG ulRCnt;
  26. ULONG ulRJCnt;
  27. ULONG ulMin;
  28. } SAMPLESTRUCT, *LPSAMPLESTRUCT;
  29. #pragma pack (pop)

转换为Go后,结构如下所示:

  1. type _Ctype_struct__sample_struct struct {
  2. usNo _Ctype_USHORT
  3. _ [8]byte
  4. cID [5]_Ctype_CHAR
  5. cCID [3]_Ctype_CHAR
  6. _ [16]byte
  7. usStat _Ctype_USHORT
  8. bAlk _Ctype_BOOL
  9. lpNNL _Ctype_LPSTRUCT2
  10. usNPCU _Ctype_USHORT
  11. _ [12]byte
  12. usType _Ctype_WORD
  13. lpszCUName _Ctype_LPSTR
  14. ulICnt _Ctype_ULONG
  15. ulDCnt _Ctype_ULONG
  16. ulPCnt _Ctype_ULONG
  17. ulRCnt _Ctype_ULONG
  18. ulRJCnt _Ctype_ULONG
  19. ulMin _Ctype_ULONG
  20. }

正如我们所看到的,一些字段没有正确转换;相反,它们有“_”。

如果没有#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:

  1. #pragma pack (push, 1)
  2. typedef struct _sample_struct
  3. {
  4. USHORT usNo;
  5. DWORD ft;
  6. DWORD fit;
  7. CHAR cID[5];
  8. CHAR cCID[3];
  9. ULONG ulVal;
  10. ULONG ulIn;
  11. ULONG ulCnt;
  12. ULONG ulMax;
  13. USHORT usStat;
  14. BOOL bAlk;
  15. LPSTRUCT2 lpNNL;
  16. USHORT usNPCU;
  17. LPSTRUCT4 * lppP;
  18. LPSTR lpBuff;
  19. LPUSHORT lpusIDS;
  20. WORD usType;
  21. LPSTR lpszCUName;
  22. ULONG ulICnt;
  23. ULONG ulDCnt;
  24. ULONG ulPCnt;
  25. ULONG ulRCnt;
  26. ULONG ulRJCnt;
  27. ULONG ulMin;
  28. } SAMPLESTRUCT, *LPSAMPLESTRUCT;
  29. #pragma pack (pop)

Converted to Go, the structure looks like below:

  1. type _Ctype_struct__sample_struct struct {
  2. usNo _Ctype_USHORT
  3. _ [8]byte
  4. cID [5]_Ctype_CHAR
  5. cCID [3]_Ctype_CHAR
  6. _ [16]byte
  7. usStat _Ctype_USHORT
  8. bAlk _Ctype_BOOL
  9. lpNNL _Ctype_LPSTRUCT2
  10. usNPCU _Ctype_USHORT
  11. _ [12]byte
  12. usType _Ctype_WORD
  13. lpszCUName _Ctype_LPSTR
  14. ulICnt _Ctype_ULONG
  15. ulDCnt _Ctype_ULONG
  16. ulPCnt _Ctype_ULONG
  17. ulRCnt _Ctype_ULONG
  18. ulRJCnt _Ctype_ULONG
  19. ulMin _Ctype_ULONG
  20. }

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)

huangapple
  • 本文由 发表于 2022年7月5日 16:28:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/72866267.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定