首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为Kotlin android、锈病和go编译库

为Kotlin android、锈病和go编译库
EN

Stack Overflow用户
提问于 2022-06-01 15:19:08
回答 1查看 216关注 0票数 0

这个问题在性质上是探索性的,不确定这是否适合堆栈重叠流Q&A。

上下文:

我有一个用golang写的库,我需要编译它以供多个服务使用。

这些服务是在Kotlin android,Rust,Golang。

我所知道的唯一选择是使用像SWIG这样的方法来编译不同语言的go库。

问题:

  1. 我不认为斯威格对Kotlin有效。

我正在努力寻找最好的方法来做到这一点,不同的方法可以做到这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-02 17:18:12

对于任何可以生成C共享库和头文件的语言,您都可以使用SWIG包装它。同样,对于在JVM中运行并可以调用Java类的任何语言,您都可以使用SWIG的自动生成的Java绑定。

因此,我们可以做一系列类似于这样的事情:

Go -> C -> JNI -> Java -> Kotlin

实际上相当理智。下面我给出了一个例子,说明它是如何工作的,因为我很好奇,以前从未写过Go或Kotlin。(因此,我可能还没有达到“最佳实践”!)

本例假设您有一个工作的JDK/JRE、C编译器、Go安装和kotlinc。

我的demo.go看起来是这样的:

代码语言:javascript
复制
package main

import (
    "C"
    "fmt"
)

//export TestGoFunc
func TestGoFunc(str *C.char) *C.char {
        fmt.Printf("Got string: %s\n", C.GoString(str))
        return nil
}

func main() {}

hello.kt看起来是这样的:

代码语言:javascript
复制
fun main() {
    println("Hello, World!")
    test.TestGoFunc("Another string")
}

为了包装这一点,我编写了以下SWIG接口:

代码语言:javascript
复制
%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接口--它将一些内容隐藏在我们不关心的生成的头文件中,并为我们在Java内部使用一个实用程序自动加载.so文件。

然后,我组装了一个小Makefile来构建所有的东西,因为这个构建有很多步骤:

代码语言:javascript
复制
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

如果我们构建并运行它,那么所有这些都能很好地工作:

代码语言:javascript
复制
$ 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来构建一个静态库,然后将它链接到SWIG共享对象中,而只是为了在这方面保持更简单。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72464343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档