我正在尝试使用 go
编写一个简单的矩阵运算 API,并将 API 公开为共享库。这个共享库将从 Java(使用 JNA)和 C 中使用。
关于使用除简单 int
或 string
之外的任何数据类型作为函数参数的文档非常少。
我的要求是将具有 1 个或多个 2D slice 的函数作为参数和返回类型公开。我无法弄清楚是否支持这样的事情。
这可能吗?有这方面的例子吗?
最佳答案
我认为关键点是查看go build
工具生成的slice、string 和int
的c 绑定(bind)。 2D slice 没试过,不过应该和1D slice 有unsafe
pointer converter 没什么区别,也许只是多了一次分配和转换。
我不确定这是最好的方法,但这是一维 slice 的示例:
开始部分:
import "C"
//export CFoo
func CFoo(content []byte) string{
var ret []byte
//blablabla to get ret
cbuf := unsafe.Pointer(C.malloc(C.size_t(len(ret))))
C.memcpy(cbuf, unsafe.Pointer(&ret[0]), C.size_t(len(ret)))
var finalString string
hdr := (*reflect.StringHeader)(unsafe.Pointer(&finalString))
hdr.Data = uintptr(unsafe.Pointer(cbuf))
hdr.Len = len(ret)
return finalString
}
用-buildmode=c-shared
编译,得到libmygo.so
。
我不知道JNA,期待它像JNI。 JNI 部分以及纯 C 部分:
#include <stdio.h>
#include <jni.h>
#include <string.h>
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt32 GoInt;
typedef GoUint32 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
JNIEXPORT JNICALL jbyteArray Java_com_mynextev_infotainment_app_myev_Native_foo(JNIEnv* env, jobject obj,jbyteArray content){
JNIEnv ienv = *env;
void * Ccontent = ienv->GetByteArrayElements(env, content, 0);
int Lcontent = ienv->GetArrayLength(env, content);
GoSlice Gcontent = {Ccontent, Lcontent, Lcontent};
if(!gret.n){
printf("jni CDoAESEnc");
return NULL;
}
jbyteArray ret = ienv->NewByteArray(env, gret.n);
ienv->SetByteArrayRegion(env, ret, 0, gret.n, gret.p);
free((void*)gret.p);
ienv->ReleaseByteArrayElements(env, content, Ccontent, JNI_ABORT);
return ret;
}
使用 libmygo.so
构建它。
最后你得到两个so
文件。一个用于 C,可以独立使用;一个用于 Java,必须与 libmygo.so
一起使用。
关于go - 在 C 共享库中公开一个带有 2D slice 作为参数的函数(通过 JNA 和 C 在 Java 中使用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36687306/