当前位置: 首页 > 面试题库 >

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

谈禄
2023-03-14
问题内容

我正在使用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,并将编译器指向标头/ dll,然后运行go get,然后执行在我的PC上打印此文件

the value of the constant is -1962924545

关于常量的读取方式/位置的上述运行变化将对H5T_NATIVE_UINT64的值给出不同的答案。但是,我很确定这不是一个正确的值,实际上,尝试使用返回ID的类型是行不通的,这并不奇怪。

如果我编写并运行“真实的” 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

谢谢!


问题答案:

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



 类似资料:
  • 我是完全新的Web API的,并试图建立一个Android应用程序观看谷歌联系人。我被Oauth的第一步卡住了。我已经完成了登录按钮和授权。按钮工作正常,我可以登录我的谷歌账户,但当我试图从这个账户获得一些东西时,日志猫打印了这个按摩“I/System_Server:oneway函数结果将被删除,但以状态OK和包裹大小结束”。为什么会这样?因为auth令牌不再有效?如何恢复权限?我应该如何从帐户获

  • 我正在使用Reverfit2,我试图从我用Python制作的Web服务中请求一些数据。 实际上,它抛出了一个“java.lang.IllegalStateException”,但是当我调用GET方法时,API返回代码200,而且我还可以看到用于调试响应JSON的打印版本。问题是Call方法,因为它总是在failure时执行。 求求你,救命! 这是我的(简单的)Python Web服务,API-Pr

  • 现在我正在学习C++我做了我的第一个小程序加法计算器,我写两个数字,它把它们相加。你能告诉我为什么我的输出是0吗? 输出:

  • 我正在使用Java NIO,由于某种原因,我无法获得files.isHidden()来返回正确的布尔值。程序只是检查目录是否隐藏,如果隐藏,则使其可见,如果不隐藏,则使其隐藏。这就是我所拥有的: 它继续返回false并隐藏目录,尽管目录被隐藏。下面的代码使用旧的File类和Path类可以很好地工作。

  • 所以,我正在为一个班级做这个作业。这是一个Java类,我应该做一个游戏,它掷两个骰子,把它们相加,然后把它们加到你的回合分数上。然后它会问你是否想继续玩下去。当你的轮次得分达到20分,或者当你决定通过时,它会进入电脑。它应该打印每个回合的分数,然后当有人得到100分时,它就会宣布胜利者。然而,不管怎样,无论我跑了多少圈,每一圈结束时的分数都是0。当一名玩家掷1时,他们的回合分数被取消,并转移到另一

  • 问题内容: 我正在创建一个小型Java Jpanel游戏,其中应该有一个火箭,它通过箭头上下移动,并通过太空射击。 触发方法应按以下方式工作:按下空格键,东西触发并在屏幕上移动,然后当它碰到某个x时,它就会消失。此外,您只能发射一次,直到另一颗子弹消失为止。 我不知道我在做什么错。首先,在我的代码启动后,您会看到子弹在屏幕上飞舞。 2,子弹没有消失。 第三,即使其他子弹仍然可见,它也允许我再次开火