这个问题本质上是探索性的,不确定这是否符合堆栈溢出Q& a
背景:
我有一个用golang编写的库,我需要为多个服务编译使用。
这些服务在Kotlin, android,Rust,Golang中。
我所知道的唯一选择是使用像SWIG这样的东西来编译不同语言的go库。
问题:
- 我不认为SWIG工作在Kotlin。
我正在努力寻找最好的方法和不同的方法来做到这一点。
对于任何可以生成C共享库和头文件的语言,都可以使用SWIG来包装它。同样,对于任何在JVM中运行并可以调用Java类的语言,您都可以使用SWIG自动生成的Java绑定。
因此,我们可以做一个序列,看起来像这样:
去→C→JNI→Java→芬兰湾的科特林
这实际上是相当理智的。我在下面放了一个例子来展示它是如何工作的,因为我以前从来没有写过Go或Kotlin。(因此,我可能还没有达到"最佳实践"的标准。!)
这个例子假设你有一个工作的JDK/JRE, C编译器,Go安装和kotlinc。
我的演示。Go是这样的:
package main
import (
"C"
"fmt"
)
//export TestGoFunc
func TestGoFunc(str *C.char) *C.char {
fmt.Printf("Got string: %sn", C.GoString(str))
return nil
}
func main() {}
和你好。Kt看起来像这样:
fun main() {
println("Hello, World!")
test.TestGoFunc("Another string")
}
为了包装它,我编写了以下SWIG接口:
%module test
%{
#include "golib.h"
%}
%include <typemaps.i>
%pragma(java) jniclasscode=%{
static {
System.loadLibrary("test");
}
%}
// Assuming you don't care about these in your library silence/neaten stuff
#define _Complex
%ignore _GoString_;
%ignore GoComplex64;
%ignore GoComplex128;
%ignore GoSlice;
%ignore GoInterface;
%include "golib.h"
这是一个针对Java的相当标准的SWIG接口-它隐藏了生成的头文件中我们不关心的一些东西,并使用一个pragma为我们自动加载Java中的。so文件。
然后我把一个小的Makefile放在一起来构建所有的东西,因为这个构建有很多步骤:
all: libtest.so hello.jar
golib.so: demo.go
go build -o golib.so -buildmode=c-shared demo.go
test_wrap.c: golib.so test.i
swig3.0 -java -Wall test.i
libtest.so: test_wrap.c
gcc -shared -Wall -Wextra test_wrap.c -o libtest.so ./golib.so -I/usr/lib/jvm/default-java/include/ -I/usr/lib/jvm/default-java/include/linux
hello.jar: hello.kt
javac *.java
kotlinc hello.kt -include-runtime -d hello.jar -cp .
jar uvf hello.jar *.class
如果我们构建并运行这个,那么它就会很好地工作:
$ make
go build -o golib.so -buildmode=c-shared demo.go
swig3.0 -java -Wall test.i
gcc -shared -Wall -Wextra test_wrap.c -o libtest.so ./golib.so -I/usr/lib/jvm/default-java/include/ -I/usr/lib/jvm/default-java/include/linux
javac *.java
kotlinc hello.kt -include-runtime -d hello.jar -cp .
jar uvf hello.jar *.class
adding: test.class(in = 302) (out= 216)(deflated 28%)
adding: testJNI.class(in = 389) (out= 268)(deflated 31%)
$ LD_LIBRARY_PATH=. java -jar hello.jar
Hello, World!
Got string: Another string
我很想使用-buildmode=c-archive
for Go来构建一个静态库,然后将其链接到SWIG共享对象中,而不是仅仅为了在这方面保持简单。