如何解决如何使用调用未定义的 c 函数的 Go 构建共享库?
我想使用 Go 创建一个共享库,供第三方软件 (STAR-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: 构建了一个示例
使用c.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.mod
module example.com/cgo_mwe
go 1.15
使用go.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
解决方法
允许链接未定义引用的三种可能解决方案。后两个位于 golang-nuts
Google Group:
- 通过
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"
- 在头文件中标记已声明但未定义的函数as weak:
#pragma weak utility
// utility function defined by third party software,declared here
extern void utility(int);
#3 的优点是未标记为弱的引用仍然被称为未定义。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。