首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用调用未定义的c函数的Go构建共享库?

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

Stack Overflow用户
提问于 2020-12-24 21:49:38
回答 1查看 3.1K关注 0票数 0

我想使用Go创建一个共享库,供第三方软件(星-CCM+)使用。该软件为代码调用提供了一些实用程序c函数,并期望我的代码至少定义一个特定函数,第三方软件将在加载库后调用该函数。

我的问题是,Go抱怨对实用程序函数的未定义引用:

代码语言:javascript
复制
/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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#include "uclib.h"

void
user_function()
{
    utility(1);
}

内部版本:

代码语言:javascript
复制
$ gcc -fPIC -c usingc.c -o usingc.o
$ gcc -shared -o libmine.so usingc.o

这将导致第三方软件成功地加载和注册其用libmine.so调用的utility函数的1。请注意,utility仅由我的代码声明,从未定义过。

有问题的例子,Go

我创建了一个简单的go模块,上面的头和两个文件:

go.mod

代码语言:javascript
复制
module example.com/cgo_mwe

go 1.15

usinggo.go

代码语言:javascript
复制
package main

// #include "uclib.h"
import "C"

//export user_function
func user_function() {
    C.utility(C.int(2))
}

func main() {}

我试图构建共享库并观察错误:

代码语言:javascript
复制
$ 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-05 18:16:29

这三种可能的解决方案允许与未定义的引用链接。第二个是在谷歌集团中找到的

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65443499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档