为什么我不能从 Golang 中正确读取 C 常量?
Why can't I read a C constant from Golang properly?
我正在使用 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/dlls 和 运行ning go get,然后在我的电脑上执行打印
the value of the constant is -1962924545
运行上面的变体,在how/where中读取常量,对于H5T_NATIVE_UINT64的值会给出不同的答案。但是我很确定 none 是正确的值,事实上尝试使用带有返回 id 的类型是行不通的,这不足为奇。
如果我编写 运行 一个 "real" 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 程序中使用它。显然我希望能够改用常量。知道为什么会这样吗?
以下评论后的额外信息:
我在hdf5headers中查找了H5T_NATIVE_UINT64的定义,看到如下
c:\HDF_Group\HDF5.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;
整个header都在这里
http://www.hdfgroup.org/ftp/HDF5/prev-releases/hdf5-1.8.14/src/unpacked/src/H5Tpublic.h
谢谢!
H5T_NATIVE_UINT64 不是常量,而是最终计算为 (H5Open(), H5T_NATIVE_UINT64_g)
的 #define,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 预处理器将转换为整型常量的任何东西。请参阅 $GOROOT/src/cmd/cgo/gcc.go
中的函数 func (p *Package) guessKinds(f *File)
。
我正在使用 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/dlls 和 运行ning go get,然后在我的电脑上执行打印
the value of the constant is -1962924545
运行上面的变体,在how/where中读取常量,对于H5T_NATIVE_UINT64的值会给出不同的答案。但是我很确定 none 是正确的值,事实上尝试使用带有返回 id 的类型是行不通的,这不足为奇。
如果我编写 运行 一个 "real" 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 程序中使用它。显然我希望能够改用常量。知道为什么会这样吗?
以下评论后的额外信息:
我在hdf5headers中查找了H5T_NATIVE_UINT64的定义,看到如下
c:\HDF_Group\HDF5.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;
整个header都在这里
http://www.hdfgroup.org/ftp/HDF5/prev-releases/hdf5-1.8.14/src/unpacked/src/H5Tpublic.h
谢谢!
H5T_NATIVE_UINT64 不是常量,而是最终计算为 (H5Open(), H5T_NATIVE_UINT64_g)
的 #define,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 预处理器将转换为整型常量的任何东西。请参阅 $GOROOT/src/cmd/cgo/gcc.go
中的函数 func (p *Package) guessKinds(f *File)
。