我正在使用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
? 提前致谢。
*编辑:定义为其他值(例如int)的常量可以正常工作。
* 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
常量给出相同的错误。一个最小的演示go程序:
package main
/*
#cgo LDFLAGS: -lldap
#include <ldap.h>
*/
import "C"
func main() {
_ = C.LDAP_SASL_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,但这可能比解决问题引起更多的麻烦。关于c - C常量的Cgo链接器错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19126160/