How to use golang c-shared library in go

huangapple go评论97阅读模式
英文:

How to use golang c-shared library in go

问题

我使用Go编写了一个C共享库。

package main

import "C"
import "log"

//export RunLib
func RunLib() {
	log.Println("Call RunLib")
}

func init() {
	log.Println("Call init")
}

func main() {
	log.Println("Call main")
}

我使用以下命令创建了该库:
go build -buildmode=c-shared -o lib.so lib.go

为了使用该库,我编写了以下Go代码。

package main

/*
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

static void callFromLib() {
	void (*fn)();
	void *h = dlopen("lib.so", RTLD_LAZY);
	if (!h) {
		fprintf(stderr, "Error: %s\n", dlerror());
		return;
	}

	*(void**)(&fn) = dlsym(h, "RunLib");
	if (!fn) {
		fprintf(stderr, "Error: %s\n", dlerror());
		dlclose(h);
		return;
	}

	fn();
	dlclose(h);
}

 */
import "C"

func main() {
	C.callFromLib()
}

如果我运行最后的代码,会抛出以下错误(go run call.go):

fatal error: bad sweepgen in refill

goroutine 1 [running, locked to thread]:
runtime.throw({0xb990782, 0xc000042a38})
        /usr/local/go/src/runtime/panic.go:1198 +0x71 fp=0xc000042a18 sp=0xc0000429e8 pc=0xb930691
runtime.(*mcache).refill(0x41215b8, 0x2)
        /usr/local/go/src/runtime/mcache.go:156 +0x24e fp=0xc000042a68 sp=0xc000042a18 pc=0xb91434e
runtime.(*mcache).nextFree(0x41215b8, 0x2)
        /usr/local/go/src/runtime/malloc.go:880 +0x85 fp=0xc000042ab0 sp=0xc000042a68 pc=0xb90ba85
runtime.mallocgc(0x8, 0xb9ba300, 0x1)
        /usr/local/go/src/runtime/malloc.go:1071 +0x4e8 fp=0xc000042b30 sp=0xc000042ab0 pc=0xb90c108
runtime.growslice(0xb9ba300, {0x0, 0x41a1910, 0x2}, 0xc00009c000)
        /usr/local/go/src/runtime/slice.go:267 +0x4ea fp=0xc000042b98 sp=0xc000042b30 pc=0xb94586a
sync.(*Pool).pinSlow(0xba394e0)
        /usr/local/go/src/sync/pool.go:223 +0x105 fp=0xc000042c30 sp=0xc000042b98 pc=0xb960ec5
sync.(*Pool).pin(0xba394e0)
        /usr/local/go/src/sync/pool.go:206 +0x4e fp=0xc000042c48 sp=0xc000042c30 pc=0xb960d8e
sync.(*Pool).Get(0xba394e0)
        /usr/local/go/src/sync/pool.go:128 +0x25 fp=0xc000042c80 sp=0xc000042c48 pc=0xb960ac5
fmt.newPrinter()
        /usr/local/go/src/fmt/print.go:137 +0x25 fp=0xc000042ca8 sp=0xc000042c80 pc=0xb985d45
fmt.Sprintln({0xc000042d38, 0x1, 0x1})
        /usr/local/go/src/fmt/print.go:280 +0x28 fp=0xc000042cf0 sp=0xc000042ca8 pc=0xb986008
log.Println({0xc000042d38, 0x24, 0x0})
        /usr/local/go/src/log/log.go:329 +0x1e fp=0xc000042d20 sp=0xc000042cf0 pc=0xb98cd5e
main.RunLib(...)
        /Users/.../demo/lib.go:8
_cgoexp_6b951f94a90e_RunLib(0xc000042d90)
        _cgo_gotypes.go:36 +0x45 fp=0xc000042d58 sp=0xc000042d20 pc=0xb98cf85
runtime.cgocallbackg1(0xb98cf40, 0xc000042e60, 0x0)
        /usr/local/go/src/runtime/cgocall.go:306 +0x29a fp=0xc000042e28 sp=0xc000042d58 pc=0xb903d1a
runtime.cgocallbackg(0xc0000001a0, 0x300000002, 0xc0000001a0)
        /usr/local/go/src/runtime/cgocall.go:232 +0x109 fp=0xc000042eb8 sp=0xc000042e28 pc=0xb9039e9
runtime.cgocallbackg(0xb98cf40, 0x7ffeefbff737, 0x0)
        <autogenerated>:1 +0x2f fp=0xc000042ee0 sp=0xc000042eb8 pc=0xb95e32f
runtime: unexpected return pc for runtime.cgocallback called from 0x4053e00
stack: frame={sp:0xc000042ee0, fp:0xc000042f08} stack=[0xc000042000,0xc000043000)
0x000000c000042de0:  0x000000c000042d9d  0x000000c000042e18 
0x000000c000042df0:  0x000000000b95843b <runtime.exitsyscall+0x00000000000000fb>  0x000000c0000001a0 
0x000000c000042e00:  0x000000c000042dd8  0x0000000000000000 
0x000000c000042e10:  0x000000000b9c3dc0  0x000000c000042ea8 
0x000000c000042e20:  0x000000000b9039e9 <runtime.cgocallbackg+0x0000000000000109>  0x000000000b98cf40 <_cgoexp_6b951f94a90e_RunLib+0x0000000000000000> 
...
<_cgoexp_6b951f94a90e_RunLib+0x0000000000000000> 
0x000000c000042ea0:  0x00007ffeefbff737  0x000000c000042ed0 
0x000000c000042eb0:  0x000000000b95e32f <runtime.cgocallbackg+0x000000000000002f>  0x000000c0000001a0 
...
<runtime.cgocallback+0x00000000000000b4> 
0x000000c000042ee0: <0x000000000b98cf40 <_cgoexp_6b951f94a90e_RunLib+0x0000000000000000>  0x00007ffeefbff737 
...
runtime.cgocallback(0x4004165, 0x4058340, 0xc000042f70)
        /usr/local/go/src/runtime/asm_amd64.s:915 +0xb4 fp=0xc000042f08 sp=0xc000042ee0 pc=0xb95c134

goroutine 1 [runnable, locked to thread]:
unicode.init()
        /usr/local/go/src/unicode/tables.go:9 +0x79
exit status 2

但是,如果我使用Python,一切都正常运行!

>>> import ctypes
>>> lib = ctypes.cdll.LoadLibrary("lib.so")
>>> 2022/03/02 01:08:17 Call init

>>> lib.RunLib()
2022/03/02 01:08:22 Call RunLib
0
>>> 

信息

操作系统:macOS Big Sur 11.6.3 (20G415)

>>> clang --version
Apple clang version 13.0.0 (clang-1300.0.29.30)
>>> go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="~/Library/Caches/go-build"
GOENV="~/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="~/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="~/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="~/projects/go/.../go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/wl/9rtfdx8x7jvgyn6t8hpq7yh00000gn/T/go-build401121298=/tmp/go-build -gno-record-gcc-switches -fno-common"

我在Google上找到了这篇文章,但文章中没有提到Go语言。

https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf

英文:

I wrote c-shared library using go.

package main

import &quot;C&quot;
import &quot;log&quot;

//export RunLib
func RunLib() {
	log.Println(&quot;Call RunLib&quot;)
}

func init() {
	log.Println(&quot;Call init&quot;)
}

func main() {
	log.Println(&quot;Call main&quot;)
}

I created the library using this command:
go build -buildmode=c-shared -o lib.so lib.go

To use the library, I wrote this golang code.

package main

/*
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;dlfcn.h&gt;

static void callFromLib() {
	void (*fn)();
	void *h = dlopen(&quot;lib.so&quot;, RTLD_LAZY);
	if (!h) {
		fprintf(stderr, &quot;Error: %s\n&quot;, dlerror());
		return;
	}

	*(void**)(&amp;fn) = dlsym(h, &quot;RunLib&quot;);
	if (!fn) {
		fprintf(stderr, &quot;Error: %s\n&quot;, dlerror());
		dlclose(h);
		return;
	}

	fn();
	dlclose(h);
}

 */
import &quot;C&quot;

func main() {
	C.callFromLib()
} 

If I run the last code it throws this error (go run call.go):

fatal error: bad sweepgen in refill

goroutine 1 [running, locked to thread]:
runtime.throw({0xb990782, 0xc000042a38})
        /usr/local/go/src/runtime/panic.go:1198 +0x71 fp=0xc000042a18 sp=0xc0000429e8 pc=0xb930691
runtime.(*mcache).refill(0x41215b8, 0x2)
        /usr/local/go/src/runtime/mcache.go:156 +0x24e fp=0xc000042a68 sp=0xc000042a18 pc=0xb91434e
runtime.(*mcache).nextFree(0x41215b8, 0x2)
        /usr/local/go/src/runtime/malloc.go:880 +0x85 fp=0xc000042ab0 sp=0xc000042a68 pc=0xb90ba85
runtime.mallocgc(0x8, 0xb9ba300, 0x1)
        /usr/local/go/src/runtime/malloc.go:1071 +0x4e8 fp=0xc000042b30 sp=0xc000042ab0 pc=0xb90c108
runtime.growslice(0xb9ba300, {0x0, 0x41a1910, 0x2}, 0xc00009c000)
        /usr/local/go/src/runtime/slice.go:267 +0x4ea fp=0xc000042b98 sp=0xc000042b30 pc=0xb94586a
sync.(*Pool).pinSlow(0xba394e0)
        /usr/local/go/src/sync/pool.go:223 +0x105 fp=0xc000042c30 sp=0xc000042b98 pc=0xb960ec5
sync.(*Pool).pin(0xba394e0)
        /usr/local/go/src/sync/pool.go:206 +0x4e fp=0xc000042c48 sp=0xc000042c30 pc=0xb960d8e
sync.(*Pool).Get(0xba394e0)
        /usr/local/go/src/sync/pool.go:128 +0x25 fp=0xc000042c80 sp=0xc000042c48 pc=0xb960ac5
fmt.newPrinter()
        /usr/local/go/src/fmt/print.go:137 +0x25 fp=0xc000042ca8 sp=0xc000042c80 pc=0xb985d45
fmt.Sprintln({0xc000042d38, 0x1, 0x1})
        /usr/local/go/src/fmt/print.go:280 +0x28 fp=0xc000042cf0 sp=0xc000042ca8 pc=0xb986008
log.Println({0xc000042d38, 0x24, 0x0})
        /usr/local/go/src/log/log.go:329 +0x1e fp=0xc000042d20 sp=0xc000042cf0 pc=0xb98cd5e
main.RunLib(...)
        /Users/.../demo/lib.go:8
_cgoexp_6b951f94a90e_RunLib(0xc000042d90)
        _cgo_gotypes.go:36 +0x45 fp=0xc000042d58 sp=0xc000042d20 pc=0xb98cf85
runtime.cgocallbackg1(0xb98cf40, 0xc000042e60, 0x0)
        /usr/local/go/src/runtime/cgocall.go:306 +0x29a fp=0xc000042e28 sp=0xc000042d58 pc=0xb903d1a
runtime.cgocallbackg(0xc0000001a0, 0x300000002, 0xc0000001a0)
        /usr/local/go/src/runtime/cgocall.go:232 +0x109 fp=0xc000042eb8 sp=0xc000042e28 pc=0xb9039e9
runtime.cgocallbackg(0xb98cf40, 0x7ffeefbff737, 0x0)
        &lt;autogenerated&gt;:1 +0x2f fp=0xc000042ee0 sp=0xc000042eb8 pc=0xb95e32f
runtime: unexpected return pc for runtime.cgocallback called from 0x4053e00
stack: frame={sp:0xc000042ee0, fp:0xc000042f08} stack=[0xc000042000,0xc000043000)
0x000000c000042de0:  0x000000c000042d9d  0x000000c000042e18 
0x000000c000042df0:  0x000000000b95843b &lt;runtime.exitsyscall+0x00000000000000fb&gt;  0x000000c0000001a0 
0x000000c000042e00:  0x000000c000042dd8  0x0000000000000000 
0x000000c000042e10:  0x000000000b9c3dc0  0x000000c000042ea8 
0x000000c000042e20:  0x000000000b9039e9 &lt;runtime.cgocallbackg+0x0000000000000109&gt;  0x000000000b98cf40 &lt;_cgoexp_6b951f94a90e_RunLib+0x0000000000000000&gt; 
...
&lt;_cgoexp_6b951f94a90e_RunLib+0x0000000000000000&gt; 
0x000000c000042ea0:  0x00007ffeefbff737  0x000000c000042ed0 
0x000000c000042eb0:  0x000000000b95e32f &lt;runtime.cgocallbackg+0x000000000000002f&gt;  0x000000c0000001a0 
...
&lt;runtime.cgocallback+0x00000000000000b4&gt; 
0x000000c000042ee0: &lt;0x000000000b98cf40 &lt;_cgoexp_6b951f94a90e_RunLib+0x0000000000000000&gt;  0x00007ffeefbff737 
...
runtime.cgocallback(0x4004165, 0x4058340, 0xc000042f70)
        /usr/local/go/src/runtime/asm_amd64.s:915 +0xb4 fp=0xc000042f08 sp=0xc000042ee0 pc=0xb95c134

goroutine 1 [runnable, locked to thread]:
unicode.init()
        /usr/local/go/src/unicode/tables.go:9 +0x79
exit status 2

But if I use python everything works correctly!

&gt;&gt;&gt; import ctypes
&gt;&gt;&gt; lib = ctypes.cdll.LoadLibrary(&quot;lib.so&quot;)
&gt;&gt;&gt; 2022/03/02 01:08:17 Call init

&gt;&gt;&gt; lib.RunLib()
2022/03/02 01:08:22 Call RunLib
0
&gt;&gt;&gt; 

Informations

OS: macOs Big Sur 11.6.3 (20G415)

&gt;&gt;&gt; clang --version
Apple clang version 13.0.0 (clang-1300.0.29.30)
&gt;&gt;&gt; nm lib.so| grep RunLib
000000000008cfa0 T _RunLib
000000000008cf40 t __cgoexp_6b951f94a90e_RunLib
00000000000c4200 s __cgoexp_6b951f94a90e_RunLib.stkobj
&gt;&gt;&gt; go env
GO111MODULE=&quot;on&quot;
GOARCH=&quot;amd64&quot;
GOBIN=&quot;&quot;
GOCACHE=&quot;~/Library/Caches/go-build&quot;
GOENV=&quot;~/Library/Application Support/go/env&quot;
GOEXE=&quot;&quot;
GOEXPERIMENT=&quot;&quot;
GOFLAGS=&quot;&quot;
GOHOSTARCH=&quot;amd64&quot;
GOHOSTOS=&quot;darwin&quot;
GOINSECURE=&quot;&quot;
GOMODCACHE=&quot;~/go/pkg/mod&quot;
GONOPROXY=&quot;&quot;
GONOSUMDB=&quot;&quot;
GOOS=&quot;darwin&quot;
GOPATH=&quot;~/go&quot;
GOPRIVATE=&quot;&quot;
GOPROXY=&quot;https://proxy.golang.org,direct&quot;
GOROOT=&quot;/usr/local/go&quot;
GOSUMDB=&quot;sum.golang.org&quot;
GOTMPDIR=&quot;&quot;
GOTOOLDIR=&quot;/usr/local/go/pkg/tool/darwin_amd64&quot;
GOVCS=&quot;&quot;
GOVERSION=&quot;go1.17&quot;
GCCGO=&quot;gccgo&quot;
AR=&quot;ar&quot;
CC=&quot;clang&quot;
CXX=&quot;clang++&quot;
CGO_ENABLED=&quot;1&quot;
GOMOD=&quot;~/projects/go/.../go.mod&quot;
CGO_CFLAGS=&quot;-g -O2&quot;
CGO_CPPFLAGS=&quot;&quot;
CGO_CXXFLAGS=&quot;-g -O2&quot;
CGO_FFLAGS=&quot;-g -O2&quot;
CGO_LDFLAGS=&quot;-g -O2&quot;
PKG_CONFIG=&quot;pkg-config&quot;
GOGCCFLAGS=&quot;-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/wl/9rtfdx8x7jvgyn6t8hpq7yh00000gn/T/go-build401121298=/tmp/go-build -gno-record-gcc-switches -fno-common&quot;

I googled and found this article. But there is no golang in the article.

https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf

答案1

得分: 6

一个Go贡献者写道,在一个镜像中不可能有两个Go运行时。这个评论是针对Windows的,但似乎也适用于macOS,因为我可以可靠地重现OP提到的崩溃:

>如果我理解正确,你正在使用一个Go程序打开一个C++ DLL,而C++ DLL打开一个Go DLL。很抱歉,在Windows上这是行不通的。在Windows上,程序镜像中只能有一个Go运行时的副本,但你正在尝试有两个。

参见https://github.com/golang/go/issues/50304#issuecomment-999302888

然而,由于OP使用的是macOS,有一个替代方案:使用插件,参见https://pkg.go.dev/plugin:
>Package plugin实现了Go插件的加载和符号解析。

创建库的命令将如下更改:

go build -buildmode=plugin -o lib.so lib.go

因此,在Go中调用定义在库中的函数的调用将如下所示:

package main

import (
	&quot;plugin&quot;
)

func main() {
	plug, err := plugin.Open(&quot;lib.so&quot;)
	if err != nil {
		panic(err)
	}

	runLib, err := plug.Lookup(&quot;RunLib&quot;)
	if err != nil {
		panic(err)
	}

	runLib.(func())()
}

使用此程序进行测试将生成以下日志输出:

stephan@mac golang-c-lib-in-go % go run call.go                                 
2022/10/29 23:23:01 Call init
2022/10/29 23:23:01 Call RunLib

如果该库还要用于从C和/或Python调用,那么一种可能性是创建两个变体的库:一个用于从C和/或Python调用,如问题中所示,另一个是插件变体,可以供Go程序使用。

在你的示例中,你不需要在lib.go中进行任何更改,唯一的区别是创建库的命令行。

最后,从文档中的一个重要说明:
>目前,插件仅在Linux、FreeBSD和macOS上受支持。

英文:

A Go contributor writes that it is not possible to have two Go runtimes in one image. The comment refers to Windows, but seems to apply to macOS as well, since I can reliably reproduce the crash mentioned by the OP:

>If I am understanding correctly, you are using a Go program to open a C++ DLL and the C++ DLL opens a Go DLL. I'm sorry, this won't work on Windows. There can only be one copy of the Go runtime in the program image on Windows, but you are trying to have two.

see https://github.com/golang/go/issues/50304#issuecomment-999302888

However since the OP uses macOS there is an alternative: the use of plugins, see https://pkg.go.dev/plugin:
>Package plugin implements loading and symbol resolution of Go plugins.

The command to create the library would change as follows:

go build -buildmode=plugin -o lib.so lib.go

Accordingly, your call to the function defined in your library would then look something like this in Go:

package main

import (
	&quot;plugin&quot;
)

func main() {
	plug, err := plugin.Open(&quot;lib.so&quot;)
	if err != nil {
		panic(err)
	}

	runLib, err := plug.Lookup(&quot;RunLib&quot;)
	if err != nil {
		panic(err)
	}

	runLib.(func())()
}

A test with this program generates the following logging outputs:

stephan@mac golang-c-lib-in-go % go run call.go                                 
2022/10/29 23:23:01 Call init
2022/10/29 23:23:01 Call RunLib

If the library is also to be used for calling from C and/or Python, then one possibility is to create the library in two variants: one that is called from C and/or Python, as shown in the question, and one in the plugin variant that can then be used by Go programs.

In your example, you don't need to make any changes in lib.go, the only difference is the command line to create the library.

Finally, an important note from the documentation:
>Currently plugins are only supported on Linux, FreeBSD, and macOS.

答案2

得分: 3

原帖中描述的问题看起来很奇怪。我在Linux上无法重现这个问题。

我的设置:Ubuntu 18,Go 1.19.2,gcc 7.5.0

我只做了一个更改:在C代码片段中添加了#cgo LDFLAGS: -ldl的编译指示。这是GCC所需的,以启用dlopen &amp; Co

package main

/*
#cgo LDFLAGS: -ldl
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

static void callFromLib() {
    void (*fn)();
    void *h = dlopen("lib.so", RTLD_LAZY);
    if (!h) {
        fprintf(stderr, "Error: %s\n", dlerror());
        return;
    }

    *(void**)(&fn) = dlsym(h, "RunLib");
    if (!fn) {
        fprintf(stderr, "Error: %s\n", dlerror());
        dlclose(h);
        return;
    }

    fn();
    dlclose(h);
}

*/
import "C"

func main() {
    C.callFromLib()
}

启动命令为:

LD_LIBRARY_PATH=/home/user/tmp/try-go/ go run call.go

LD_LIBRARY_PATH变量指向包含lib.so的目录

输出:

2022/10/26 09:39:10 Call init
2022/10/26 09:39:10 Call RunLib

如预期,没有错误。

原始错误bad sweepgen in refill是垃圾收集器引发的。对象缓存变得不一致。我怀疑问题是程序中存在两个运行时和两个垃圾收集器 - 一个来自调用程序,另一个来自加载的lib.so。看起来两个垃圾收集器在同一堆上运行时发生了冲突。

无论如何,在Go 1.19中,该代码是可以工作的。但我不会通过C的dlopen加载Go共享对象 - 谁知道两个Go运行时如何交互,特别是如果它们来自不同的编译器版本。

英文:

The problem described by the original poster looks weird. I could not reproduce it on Linux.

My setup: Ubuntu 18, Go 1.19.2, gcc 7.5.0

I made only one change: added pragma #cgo LDFLAGS: -ldl to the C snippet. It is required by GCC to enable dlopen &amp; Co.

package main

/*
#cgo LDFLAGS: -ldl
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;dlfcn.h&gt;

static void callFromLib() {
    void (*fn)();
    void *h = dlopen(&quot;lib.so&quot;, RTLD_LAZY);
    if (!h) {
        fprintf(stderr, &quot;Error: %s\n&quot;, dlerror());
        return;
    }

    *(void**)(&amp;fn) = dlsym(h, &quot;RunLib&quot;);
    if (!fn) {
        fprintf(stderr, &quot;Error: %s\n&quot;, dlerror());
        dlclose(h);
        return;
    }

    fn();
    dlclose(h);
}

*/
import &quot;C&quot;

func main() {
	C.callFromLib()
}

Launched as:

LD_LIBRARY_PATH=/home/user/tmp/try-go/ go run call.go

LD_LIBRARY_PATH variable points to the directory with lib.so

Output:

2022/10/26 09:39:10 Call init
2022/10/26 09:39:10 Call RunLib

As expected, no errors.

The original error bad sweepgen in refill is raised by the garbage collector. The cache of objects became incoherent. I suspect the issue is that there are two runtimes and two garbage collectors in the program - one comes from the calling program and the other is from the loaded lib.so. It looks like two garbage collectors clashed while running over the same heap.

Anyway, in go 1.19 the code works. Still I wouldn't load Go shared object through C dlopen - who knows how two Go runtimes could interact, especially if they are from different compilers versions.

答案3

得分: -1

我建议阅读这篇详细讨论了如何将Go程序与C库链接的博客

你的Go程序中的代码似乎缺少编译器和链接器的指令:

#cgo CFLAGS: -I./src

#cgo LDFLAGS: -L./lib -lmylib -Wl,-rpath=./lib

英文:

I suggest this blog which discusses linking go programs with c libraries in detail.

Your code in the go program seems to be missing the compiler and linker instructions:

#cgo CFLAGS: -I./src

#cgo LDFLAGS: -L./lib -lmylib -Wl,-rpath=./lib

huangapple
  • 本文由 发表于 2022年3月2日 04:26:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/71314253.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定