我正在使用cgo来包装C库并遇到一组奇怪的链接器错误。我把问题归结为以下几点:
文件header.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 "header.h"
*/
import "C"
func main() {
_ = C.CONSTANT1
_ = C.CONSTANT2
_ = C.CONSTANT3
_ = C.CONSTANT4
}
运行go run test.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
?提前致谢。
*编辑:定义为其他值(例如整数)的常量可以正常工作。
* Edit2:使用go版本go1.1.2 linux / amd64
* Edit3:失败的完整示例:
我正在使用C OpenLDAP库,并希望使用LDAP_SASL_SIMPLE
常量。它在ldap.h
中定义为
#define LDAP_SASL_SIMPLE ((char*)0)
#define LDAP_SASL_NULL ("")
LDAP_SASL_NULL
常量给出相同的错误。
最小的示范性计划:
package main
/*
#cgo LDFLAGS: -lldap
#include <ldap.h>
*/
import "C"
func main() {
_ = C.LDAP_SASL_SIMPLE
}
答案 0 :(得分:0)
我最初根据我认为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,但这可能比解决问题更麻烦。