为什么我不能正确地从Golang读取C常量?

时间:2015-02-10 21:50:05

标签: c go mingw hdf5

我使用go-hdf5将hdf5文件读入golang。我在windows7上使用了最近的mingw和hdf5 1.8.14_x86副本,似乎尝试使用任何预定义的类型都不起作用,让我们专注于例如T_NATIVE_UINT64。我已经将问题简化为以下内容,这基本上让go-hdf5摆脱了问题并指出了一些非常根本的错误:

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 <stdio.h>

 void print_the_value2() { printf("the value of the constant is %d\n", H5T_NATIVE_UINT64); }
*/
import "C"

func main() {
    C.print_the_value2()
}

你显然需要拥有hdf5并将编译器指向headers / dll并运行go get,然后在我的电脑上执行打印

the value of the constant is -1962924545

运行上述变量,在读取常量的方式/位置,将为H5T_NATIVE_UINT64的值提供不同的答案。但是我很确定没有一个是正确的值,实际上尝试使用返回id的类型并不令人惊讶。

如果我写一个&#34;真实&#34; C程序,我得到不同的结果

#include <stdio.h>
#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());
}

使用

进行编译
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

跑步给了我

the value of the constant is 50331683

这似乎是正确的价值,因为我可以直接从我的go程序中使用它。显然我希望能够使用常量。知道为什么会发生这种情况吗?

以下评论后的额外信息:

我在hdf5标头中查找了H5T_NATIVE_UINT64的定义,并参见以下内容

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;

整个标题在这里

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

谢谢!

1 个答案:

答案 0 :(得分:0)

H5T_NATIVE_UINT64不是常数,而是#define,最终评估为(H5Open(), H5T_NATIVE_UINT64_g),cgo不理解。

通过打开gcc预处理器上的调试输出,可以轻松检查:

gcc -E -dM your_test_c_file.c | grep H5T_NATIVE_UINT64

结果:

#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g)

现在H5OPEN也一样:

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

给出:

#define H5OPEN H5open(),

现在,cgo确实理解像#define VALUE 1234这样的简单整数常量定义,或者gcc预处理器将变为整数常量的任何东西。查看func (p *Package) guessKinds(f *File)中的$GOROOT/src/cmd/cgo/gcc.go函数。