C常量上的Cgo链接器错误
我使用cgo包装一个C库,遇到了一组奇怪的链接器错误。我把问题归结为以下几点: 文件头.h包含C常量上的Cgo链接器错误,c,linker,go,ld,cgo,C,Linker,Go,Ld,Cgo,我使用cgo包装一个C库,遇到了一组奇怪的链接器错误。我把问题归结为以下几点: 文件头.h包含 #ifndef HEADER_H #define HEADER_H #define CONSTANT1 ("") #define CONSTANT2 "" #define CONSTANT3 ((char*)0) #define CONSTANT4 (char*)0 #endif /* HEADER_H */ 和test.go包含 package main /* #include "heade
#ifndef HEADER_H
#define HEADER_H
#define CONSTANT1 ("")
#define CONSTANT2 ""
#define CONSTANT3 ((char*)0)
#define CONSTANT4 (char*)0
#endif /* HEADER_H */
和test.go包含
package main
/*
#include "header.h"
*/
import "C"
func main() {
_ = C.CONSTANT1
_ = C.CONSTANT2
_ = C.CONSTANT3
_ = C.CONSTANT4
}
运行go运行测试时。go
我得到以下错误:
# command-line-arguments
... _cgo_main.o:(.data.rel+0x0): undefined reference to `CONSTANT4'
... _cgo_main.o:(.data.rel+0x8): undefined reference to `CONSTANT3'
... _cgo_main.o:(.data.rel+0x10): undefined reference to `CONSTANT1'
collect2: ld returned 1 exit status
关于这一点,我有两个问题:
CONSTANT1
,CONSTANT3
,CONSTANT4
显示为未定义,而不是CONSTANT2
LDAP\u SASL\u SIMPLE
常量。它在ldap.h
中定义为
#define LDAP_SASL_SIMPLE ((char*)0)
#define LDAP_SASL_NULL ("")
LDAP\u SASL\u NULL
常量给出了相同的错误
最低限度的演示性围棋程序:
package main
/*
#cgo LDFLAGS: -lldap
#include <ldap.h>
*/
import "C"
func main() {
_ = C.LDAP_SASL_SIMPLE
}
主程序包
/*
#cgo LDFLAGS:-lldap
#包括
*/
输入“C”
func main(){
_=C.LDAP\u SASL\u SIMPLE
}
根据我认为cgo的工作原理,我最初的回答有所不同。但是,如果cgo识别出CONSTANT2
,那么原因可能就不同了。请你:
- 在库文件上运行工具
,告诉输出是否包含nm
,或者您引用的任何其他常量,这些常量是通过CONSTANT2
同时建立的。库可能会声明一个#define
常量,同时声明一个全局符号,以避免兼容性问题#define
- 如果可能的话,为你的问题提供一个最小的工作示例。这是一个可以由阅读你文章并展示你问题的人编写的示例。你的问题看起来可能会遗漏一些重要的部分来回答。例如,了解您遇到问题的实际库会很好
原始答案 如果使用
#define
,则不会建立编译器实际看到的任何内容。#define
是在解析之前删除的预处理指令。要建立编译器(以及cgo)可以看到的常量,请实际声明它们:
const char *CONSTANT1 = "";
const char *CONSTANT2 = "";
const char *CONSTANT3 = (char*)0;
const char *CONSTANT4 = (char*)0;
如果你不能触摸标题,通常你做不了多少;基本上,您必须复制代码Go部分中的所有常量:
const (
CONSTANT1 = "",
CONSTANT2 = "",
CONSTANT3 = nil,
CONSTANT4 = nil,
)
您可以尝试一些复杂的技巧,比如在Go代码上运行cpp,但这可能会带来比解决问题更多的麻烦。Wild guess;如果正确:Go希望使用符号名通过ABI(正确链接)访问数据。这不是预处理器宏所做的。(我可能错了,因为我从来没有使用过Go。)@fuzzxl(现在猜猜是谁在不懂这些语言的情况下解决了几个Java、Python和Lua“问题…”:P)嗯。。。我猜这是因为其他常量封装在大括号中或包含可能会混淆cgo的类型转换。如果您能展示一个展示您的问题的最小完整示例,那就太好了。如果你能链接到实际的库,那就最好了。记录如下:我删除的评论(最初是第二条)读到:@H2CO3你是对的。我删除了它,因为我被OP的问题弄糊涂了,于是问我自己。你说其中一个常数有效,而另一个常数无效。哪一个有用?对于您提供的示例,我的原始示例适用。您需要在Go代码中重新定义常量。