我正在使用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

我对此有两个问题:
  • 为什么链接器与预定义常量有关系?
  • 为什么CONSTANT1CONSTANT3CONSTANT4显示为未定义,但未显示为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/

    10-16 20:44