微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用调用未定义的 c 函数的 Go 构建共享库?

如何解决如何使用调用未定义的 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 模块:

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:

  1. 通过 LDFLAGS-shared 忽略所有未定义的引用
// #include "uclib.h"
// #cgo LDFLAGS: -shared
import "C"
  1. 通过 LDFLAGS-Wl,-unresolved-symbols=ignore-all 忽略所有未定义的引用:
// #include "uclib.h"
// #cgo LDFLAGS: -Wl,-unresolved-symbols=ignore-all
import "C"
  1. 在头文件中标记已声明但未定义的函数as weak
#pragma weak utility
// utility function defined by third party software,declared here
extern void utility(int);

#3 的优点是未标记为弱的引用仍然被称为未定义。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。