在 iOS 和 Android 上运行 Go 代码
在本教程中 , 我们将构建一个简单的 Go 包 , 您可以从 iOS 应用程序(Swift)和 Android 应用程序(Kotlin)运行该软件包 。
本教程不会使用 go mobile [1] 框架 。 相反 , 它使用 Cgo 构建可导入到您的移动项目中的原始静态(iOS)和共享(android) C 库(Go Mobile 框架在后台进行此操作) 。
构建在本教程中 , 我们将创建具有以下结构的简单 monorepo:
.├── android/├── go/│├── cmd/││└── libfoo/││└── main.go│├── foo/││└── foo.go│├── go.mod│└── go.sum└── ios/$ mkdir -p android ios go/cmd/libfoo go/foo
我们将从 Go 代码开始 , 稍后再返回创建 iOS 和 Android 项目 。
$ cd go$ go mod init rogchap.com/libfoo
Foo 包// go/foo/foo.gopackage foo// Reverse reverses the given string by each utf8 characterfunc Reverse(in string) string {n := 0rune := make([]rune, len(in))for _, r := range in {rune[n] = rn++}rune = rune[0:n]for i := 0; i < n/2; i++ {rune[i], rune[n-1-i] = rune[n-1-i], rune[i]}return string(rune)}
我们的 foo 程序包有一个函数 Reverse, 该函数具有单个字符串参数 in 和单个字符串输出 。
导出为 C为了使我们的 C 库调用我们的 foo 包 , 我们需要导出所有要公开给 C 的函数 , 并带有特殊 export 注释 。 该包装器必须位于 main 包装中:
// go/cmd/libfoo/main.gopacakge mainimport "C"// other imports should be seperate from the special Cgo importimport ("rogchap.com/libfoo/foo")//export reversefunc reverse(in *C.char) *C.char {return C.CString(foo.Reverse(C.GoString(in)))}func main() {}
我们正在使用特殊的 C.GoString() 和 C.CString() 函数在 Go 字符串和 C 字符串之间进行转换 。
*注意:*我们要导出的函数不必是导出的 Go 函数(即以大写字母开头) 。 还要注意是空 main 函数;这对于 Go 代码进行编译是必需的 , 否则会出现 function main is undeclared in the main package 错误 。
让我们通过使用 -buildmode 标志创建一个静态 C 库来测试我们的构建:
go build -buildmode=c-archive -o foo.a ./cmd/libfoo
这应该已经输出了 C 库: foo.a 和头文件: foo.h。 您应该在头文件的底部看到导出的函数:
extern char* reverse(char* in);
为 iOS 构建我们的目标是创建一个可以在 iOS 设备和 iOS 模拟器上使用的 Fat 二进制文件 [2]。
Go 标准库包含用于构建 iOS 的脚本: `$GOROOT/misc/ios/clangwrap.sh` [3], 但是该脚本仅针对生成 arm64, 而 x86_64 iOS Simulator 也需要该脚本。 因此 , 我们将创建自己的 clangwrap.sh :
#!/bin/sh# go/clangwrap.shSDK_PATH=`xcrun --sdk $SDK --show-sdk-path`CLANG=`xcrun --sdk $SDK --find clang`if [ "$GOARCH" == "amd64" ]; thenCARCH="x86_64"elif [ "$GOARCH" == "arm64" ]; thenCARCH="arm64"fiexec $CLANG -arch $CARCH -isysroot $SDK_PATH -mios-version-min=10.0 "$@"
不要忘记让它可执行:
chmod +x clangwrap.sh
现在 , 我们可以为每种体系结构构建库 , 并使用该 lipo 工具(通过 Makefile)合并为 Fat 二进制文件:
# go/Makefileios-arm64: CGO_ENABLED=1 \ GOOS=darwin \ GOARCH=arm64 \ SDK=iphoneos \ CC=$(PWD)/clangwrap.sh \ CGO_CFLAGS="-fembed-bitcode" \ go build -buildmode=c-archive -tags ios -o $(IOS_OUT)/arm64.a ./cmd/libfooios-x86_64: CGO_ENABLED=1 \ GOOS=darwin \ GOARCH=amd64 \ SDK=iphonesimulator \ CC=$(PWD)/clangwrap.sh \ go build -buildmode=c-archive -tags ios -o $(IOS_OUT)/x86_64.a ./cmd/libfooios: ios-arm64 ios-x86_64 lipo $(IOS_OUT)/x86_64.a $(IOS_OUT)/arm64.a -create -output $(IOS_OUT)/foo.a cp $(IOS_OUT)/arm64.h $(IOS_OUT)/foo.h
推荐阅读
- 诺基亚为何宁可逐渐没落也不采用Android系统?长知识了
- iOS版微信又双更新了,AirPods Pro推出牛年限定款
- 苹果关闭iOS 14.2/14.2.1认证通道:iOS 14.3无法降级
- 灯塔市税务局首个5G智慧办税厅开始试运行
- 初探 iOS 自动化工具——快捷指令
- Axiomtek推出AIE100-903-FL-NX AI Edge系统 可在恶劣环境下运行
- 联想发布新款11英寸Android平板电脑Tab P11
- 苹果iOS 14升级这么久,这10个隐藏功能你未必全知道
- 苹果重拳出击,IOS系统再次迎来更新,果粉这下有福了
- 为规避隐私标签不再更新ios应用?谷歌:或将本周更新