GO的模块项目如何编译为能被C调用的静态库或动态库

问题描述

GO的模块如何编译为能被C调用的静态库或动态库呢?其中这个模块也有引用,这些引用都是来自github的的。
GO的模块代码其中引用代码也是 github.com/* 类似这种

最佳答案

先使用 github.com/spf13/cast 库来编写一个字符串转数字的函数 myatoi。然后编译动态库,并使用 C 调用 myatoi

编写 Go 代码

main.go

package main

// 编译源码里必须有main package

import (
    "C" // 源码必须import "C"

    "github.com/spf13/cast"
)

// 导出符号位于main package,且前一行有//export NAME,注意// 与  export 中间不能有空格
//
//export myatoi
func myatoi(s string) int {
    return cast.ToInt(s)
}

func main() {}

编译动态库

$ go build -buildmode=c-archive -o libconv.a  main.go

编译后会在当前文件夹生成 libconv.a 与 libconv.h 文件

编写 C 代码使用动态库

main.c

#include <stdio.h>

#include "libconv.h"

int main(int argc, char const *argv[])
{
    GoString s = {"123r", 3};// 有意输入字母 r
    GoInt i = myatoi(s);
    printf("call go atoi %lld\n", i);
    return 0;
}

测试

$ cc main.c -o conv -L ./ -l conv && ./conv
# 输出:call go atoi 123
1年前 评论
讨论数量: 2

先使用 github.com/spf13/cast 库来编写一个字符串转数字的函数 myatoi。然后编译动态库,并使用 C 调用 myatoi

编写 Go 代码

main.go

package main

// 编译源码里必须有main package

import (
    "C" // 源码必须import "C"

    "github.com/spf13/cast"
)

// 导出符号位于main package,且前一行有//export NAME,注意// 与  export 中间不能有空格
//
//export myatoi
func myatoi(s string) int {
    return cast.ToInt(s)
}

func main() {}

编译动态库

$ go build -buildmode=c-archive -o libconv.a  main.go

编译后会在当前文件夹生成 libconv.a 与 libconv.h 文件

编写 C 代码使用动态库

main.c

#include <stdio.h>

#include "libconv.h"

int main(int argc, char const *argv[])
{
    GoString s = {"123r", 3};// 有意输入字母 r
    GoInt i = myatoi(s);
    printf("call go atoi %lld\n", i);
    return 0;
}

测试

$ cc main.c -o conv -L ./ -l conv && ./conv
# 输出:call go atoi 123
1年前 评论

OK,我后面测试下,感谢回复 :+1:

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!