Pourquoi est-ce que je ne peux pas lire correctement une constante C de Golang?

J’utilise go-hdf5 pour lire un fichier hdf5 dans golang. Je suis sur Windows7 en utilisant une copie assez récente de Mingw et hdf5 1.8.14_x86 et il semble que d’essayer d’utiliser l’un des types prédéfinis ne fonctionne pas, concentrons-nous par exemple sur T_NATIVE_UINT64. J’ai réduit le problème à ce qui suit, ce qui laisse fondamentalement go-hdf5 à l’écart du problème et signale un problème fondamental qui pourrait mal tourner:

package main /* #cgo CFLAGS: -IC:/HDF_Group/HDF5/1.8.14_x86/include #cgo LDFLAGS: -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl #include "hdf5.h" #include  void print_the_value2() { printf("the value of the constant is %d\n", H5T_NATIVE_UINT64); } */ import "C" func main() { C.print_the_value2() } 

Vous devez évidemment avoir hdf5 et pointer le compilateur vers les en-têtes / dll et exécuter go get, puis exécuter des impressions sur mon PC

 the value of the constant is -1962924545 

Les variations courantes de ce qui précède, dans comment / où la constante est lue, donneront des réponses différentes pour la valeur de H5T_NATIVE_UINT64. Cependant, je suis à peu près sûr que rien n’est la bonne valeur et en fait, essayer d’utiliser un type avec l’id retourné ne fonctionne pas, sans surprise.

Si j’écris et exécute un “vrai” programme C, j’obtiens des résultats différents

 #include  #include "hdf5.h" hid_t _go_hdf5_H5T_NATIVE_UINT64() { return H5T_NATIVE_UINT64; } int main() { printf("the value of the constant is %d", _go_hdf5_H5T_NATIVE_UINT64()); } 

Comstackr en utilisant

 C:\Temp>gcc -IC:/HDF_Group/HDF5/1.8.14_x86/include -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl -o stuff.exe stuff.c 

et courir me donne

 the value of the constant is 50331683 

Et cela semble être la bonne valeur car je peux l’utiliser directement à partir de mon programme go. Évidemment, je veux pouvoir utiliser les constantes à la place. Une idée pourquoi cela pourrait se produire?

Informations supplémentaires après les commentaires ci-dessous:

Je cherchais la définition de H5T_NATIVE_UINT64 dans les en-têtes hdf5 et voyais ce qui suit

 c:\HDF_Group\HDF5\1.8.14_x86\include>grep H5T_NATIVE_UINT64 * H5Tpkg.h:H5_DLLVAR size_t H5T_NATIVE_UINT64_ALIGN_g; H5Tpublic.h:#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g) H5Tpublic.h:H5_DLLVAR hid_t H5T_NATIVE_UINT64_g; 

L’en-tête entier est ici

http://www.hdfgroup.org/ftp/HDF5/prev-releases/hdf5-1.8.14/src/unpacked/src/H5Tpublic.h

Merci!

H5T_NATIVE_UINT64 n’est PAS une constante, mais une #define dont le résultat final est évalué à (H5Open(), H5T_NATIVE_UINT64_g) , ce que cgo ne comprend pas.

Il est facile de vérifier en activant la sortie de débogage sur le préprocesseur de gcc:

 gcc -E -dM your_test_c_file.c | grep H5T_NATIVE_UINT64 

Résultat:

 #define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g) 

Maintenant la même chose pour H5OPEN:

 gcc -E -dM test_go.c | grep '#define H5OPEN' 

donne:

 #define H5OPEN H5open(), 

À l’heure actuelle, cgo comprend la constante entière simple définie comme #define VALUE 1234 , ou tout ce que le pré-processeur gcc va transformer en une constante entière. Voir la fonction func (p *Package) guessKinds(f *File) dans $GOROOT/src/cmd/cgo/gcc.go