java - 使用 cgo 从 Go 返回 String[]

标签 java go jna cgo

我必须从 Java 调用 Go 函数。 我使用 cgoJNA 来执行此操作。

Go 例程所做的唯一事情就是分配内存并返回一个 char**。从 Java 方面,我使用 String[] 接收 char**,如 documentation 中所述。 .

以下是 C 帮助程序和 Go 函数的详细信息:

static char** cmalloc(int size) {
    return (char**) malloc(size * sizeof(char*));
}

static void setElement(char **a, char *s, int index) {
    a[index] = s;
}

//export getSearchKeysA
func getSearchKeysA() **C.char {
    set_char := C.cmalloc(1)
    defer C.free(unsafe.Pointer(set_char))
    C.setElement(set_char, C.CString("hello world"), C.int(0))
    return set_char
}

Java 端:

String[] getSearchKeysA();

我收到的错误是:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fff6b15323e, pid=92979, tid=0x0000000000000c07
#
# JRE version: Java(TM) SE Runtime Environment (8.0_192-b12) (build 1.8.0_192-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.192-b12 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libsystem_kernel.dylib+0x723e]  __pthread_kill+0xa
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/dfb3/datafabric/pocs/go-java-connector/hs_err_pid92979.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

我注意到问题是在 malloc 分配内存时出现的。

我已经尝试执行ulimit -c unlimited并从方法中删除defer C.free(unsafe.Pointer(set_char))

导致该错误的原因是什么以及如何解决?是否有其他方法使用 JNA 从 Go 返回 []string

由于拼写错误并基于 @PeterSO 答案进行更新:

  1. 我最初写的是malloc(0),但应该是malloc(1)
  2. func C.CString(string) *C.char,它应该为我分配内存,是 不是吗?

最佳答案

我终于可以使用 cgoGO 返回一个 String[]

我将留下函数签名:

//export getSearchKeys
func getSearchKeys(numKeysByReference *C.int) **C.char {
  *numKeysByReference = // ... some value
  // Using the C helper defined above
  set_char := C.cmalloc(*numKeysByReference)
  // Logic allocating and populating C.char[i .. *numKeysByReference]
  // ...
  return set_char
}

使用cgo创建**C.char结构后,在Java端,我收到如下数据:

IntByReference intByReference = new IntByReference();
PointerByReference array = lib.getSearchKeys(intByReference);
String[] results = array.getPointer().getStringArray(0, intByReference.getValue());

正如@PeterSO提到的,我们在使用它后调用了defer C.free()。否则,返回后将被释放。

关于java - 使用 cgo 从 Go 返回 String[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59495888/

相关文章:

Go get path 是 GOROOT,而不是 GOPATH 错误,即使在 Windows 中设置了 env

java - 包含 char* 的结构的内存访问无效

java - 如何从 cgo 返回的 C 字符串中释放 java 中的内存(使用 jna)?

java - 如果socketaccept导致异常,如何找出原因?

java - 如何使用servlet在mysql中保存表情符号

go - 防止修改结构数据成员的惯用方法

reflection - 如何使用反射初始化结构值字段?

java - 使用 jna 加载 lib.so

java - 在 Android 中读取 JSON 文件并出现 API 问题

Java 套接字 readInt EOFException