+
81
-

golang如何生成c语言可以调用的动态库.so和静态库.a?

go

请问golang如何生成c语言可以调用的动态库.so和静态库.a?

网友回复

+
1
-

我们先看看golang的buildmode命令解释

go help buildmode
The 'go build' and 'go install' commands take a -buildmode argument which
indicates which kind of object file is to be built. Currently supported values
are:

    -buildmode=archive
        Build the listed non-main packages into .a files. Packages named
        main are ignored.

    -buildmode=c-archive
        Build the listed main package, plus all packages it imports,
        into a C archive file. The only callable symbols will be those
        functions exported using a cgo //export comment. Requires
        exactly one main package to be listed.

    -buildmode=c-shared
        Build the listed main package, plus all packages it imports,
        into a C shared library. The only callable symbols will
        be those functions exported using a cgo //export comment.
        Requires exactly one main package to be listed.

    -buildmode=default
        Listed main packages are built into executables and listed
        non-main packages are built into .a files (the default
        behavior).

    -buildmode=shared
        Combine all the listed non-main packages into a single shared
        library that will be used when building with the -linkshared
        option. Packages named main are ignored.

    -buildmode=exe
        Build the listed main packages and everything they import into
        executables. Packages not named main are ignored.

    -buildmode=pie
        Build the listed main packages and everything they import into
        position independent executables (PIE). Packages not named
        main are ignored.

    -buildmode=plugin
        Build the listed main packages, plus all packages that they
        import, into a Go plugin. Packages not named main are ignored.

如何要编译成c的动态库的话就要使用buildmode=c-shared,新建一个文件libhello.go

package main

import "C"
import "fmt"

//export Sum
func Sum(a int, b int) int {
    return a + b
}

//export GetName
func GetName(firstName string) string{
    return fmt.Sprint(firstName,"-so")
}

func main(){

}

注意,即使是要编译成动态库,也要有main函数,上面的import "C"一定要有 而且一定要有注释

go build -buildmode=c-shared -o libhello.so .\libhello.go

然后我们看c怎么调用

把libhello.so拷贝到/usr/lib中用于运行 新建一个文件夹hello_test ,把libhello.so libhello.h拷贝到文件夹hello_test中 把libhello.h中到GoString类型更改为_GoString 创建main.c,内容如下:

#include <stdio.h>
#include "libhello.h"
 
void main()
{
    _GoString str;
    str = GetName("bfw");    
    printf("%d\n",str.n);
}

编译命令如下:gcc main.c -o t1 -I./ -L./ -lhello

我知道答案,我要回答