我想使用Go创建一个共享库,供第三方软件(星-CCM+)使用。该软件为代码调用提供了一些实用程序c函数,并期望我的代码至少定义一个特定函数,第三方软件将在加载库后调用该函数。
我的问题是,Go抱怨对实用程序函数的未定义引用:
/tmp/go-build672782048/b001/_x002.o: In function `_cgo_c4b84da031f3_Cfunc_utility':
/tmp/go-build/cgo-gcc-prolog:50: undefined reference to `utility'如何编译一个调用声明但未由代码定义的c函数的共享库?
第三方软件提供了一个类似于此的头文件:
uclib.h
#ifndef UCLIB_H
#define UCLIB_H
// utility function defined by third party software, declared here
extern void utility(int);
// function expected to exist in .so and defined by user
// this function is expected to call `utility` one or more times
void user_function();
#endif工作示例,仅c
为了测试与第三方软件的交互,我只使用c构建了一个示例:
usingc.c
#include "uclib.h"
void
user_function()
{
utility(1);
}内部版本:
$ gcc -fPIC -c usingc.c -o usingc.o
$ gcc -shared -o libmine.so usingc.o这将导致第三方软件成功地加载和注册其用libmine.so调用的utility函数的1。请注意,utility仅由我的代码声明,从未定义过。
有问题的例子,Go
我创建了一个简单的go模块,上面的头和两个文件:
go.mod
module example.com/cgo_mwe
go 1.15usinggo.go
package main
// #include "uclib.h"
import "C"
//export user_function
func user_function() {
C.utility(C.int(2))
}
func main() {}我试图构建共享库并观察错误:
$ go build -o libmineg.so -buildmode=c-shared
# example.com/cgo_mwe
/tmp/go-build672782048/b001/_x002.o: In function `_cgo_c4b84da031f3_Cfunc_utility':
/tmp/go-build/cgo-gcc-prolog:50: undefined reference to `utility'
collect2: error: ld returned 1 exit status发布于 2021-01-05 18:16:29
这三种可能的解决方案允许与未定义的引用链接。第二个是在谷歌集团中找到的
LDFLAGS和-shared忽略所有未定义的引用// #include "uclib.h"
// #cgo LDFLAGS: -shared
import "C"LDFLAGS和-Wl,-unresolved-symbols=ignore-all忽略所有未定义的引用// #include "uclib.h"
// #cgo LDFLAGS: -Wl,-unresolved-symbols=ignore-all
import "C"#pragma weak utility
// utility function defined by third party software, declared here
extern void utility(int);#3的优点是,未标记为弱的引用仍被称为未定义的引用。
https://stackoverflow.com/questions/65443499
复制相似问题