You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用单一Go包适配cgo与gomobile构建多平台库?

解决方案:拆分核心逻辑与CGo入口层

不用重复编写代码,只需要把核心库逻辑放在非main包,再单独写一个极简的main包作为CGo的适配入口即可,完美兼容两种构建方式。

1. 重构代码结构

  • 核心库包:将所有业务逻辑、暴露给外部的函数/类型都放在一个非main包中(比如./golibs),这部分代码是跨构建方式共享的核心。
  • CGo入口包:新建一个独立的main包目录(比如./cmd/cgoentry),仅作为CGo导出函数的薄适配层,完全复用核心库的代码。

2. 代码示例

核心库代码(./golibs/lib.go)

package golibs

// 示例核心功能:加法
func Add(a, b int) int {
    return a + b
}

// 示例核心功能:生成问候语
func Greet(name string) string {
    return "Hello, " + name
}

CGo入口代码(./cmd/cgoentry/main.go)

package main

/*
#include <stdlib.h>
*/
import "C"
import "../golibs" // 根据实际路径调整,或使用模块路径
import "unsafe"

//export Add
func Add(a C.int, b C.int) C.int {
    // 调用核心库函数,仅做类型转换
    return C.int(golibs.Add(int(a), int(b)))
}

//export Greet
func Greet(name *C.char) *C.char {
    goStr := golibs.Greet(C.GoString(name))
    // 将Go字符串转为C字符串,注意需要提供释放函数
    return C.CString(goStr)
}

//export FreeString
func FreeString(s *C.char) {
    // 提供给C端释放内存的函数
    C.free(unsafe.Pointer(s))
}

// 空main函数,满足CGo对main包的要求
func main() {}

3. 调整构建命令

CGo静态/共享库构建(针对main入口包)

# Windows共享库
go build -buildmode=c-shared -o libraries/golibs.dll ./cmd/cgoentry
# Linux/macOS共享库
go build -buildmode=c-shared -o libraries/golibs.so ./cmd/cgoentry
# Windows静态库
go build -buildmode=c-archive -o libraries/golibs.lib ./cmd/cgoentry
# Linux/macOS静态库
go build -buildmode=c-archive -o libraries/golibs.a ./cmd/cgoentry

Gomobile移动库构建(针对核心非main包)

gomobile bind -target=android -androidapi 19 -o libraries/mobile/golibs.aar -v ./golibs

4. 优势说明

  • 核心逻辑仅编写维护一次,避免重复代码。
  • CGo入口层仅做类型转换和函数导出,几乎无维护成本。
  • 完全满足两种构建工具的包要求,无冲突。

内容的提问来源于stack exchange,提问作者Leonardo Paci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:15:29