Return 来自 Go 使用 cgo 的 String[]
Return String[] from Go using cgo
我必须从 Java 调用 Go 函数。
我正在使用 cgo
和 JNA
来执行此操作。
Go 例程所做的唯一事情就是分配内存和 return char**
。从 Java 方面,我正在使用 String[]
接收 char**
,如 documentation 中所述。
以下是 C helper 和 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 中 returning a []string
?
由于打字错误和基于@PeterSO 回答的更新:
- 我最初写的是 malloc(0) 但它应该是 malloc(1)
func C.CString(string) *C.char
,它应该给我分配内存,是
不是吗?
你写:
func getSearchKeysA() **C.char {
set_char := C.cmalloc(0)
defer C.free(unsafe.Pointer(set_char))
C.setElement(set_char, C.CString("hello world"), C.int(0))
return set_char
}
可能执行为:
func getSearchKeysA() (retval **C.char) {
set_char := C.cmalloc(42)
C.setElement(set_char, C.CString("hello world"), C.int(1))
retval = set_char
C.free(unsafe.Pointer(set_char))
return retval
}
你指的是 free
之后的 set_char
吗?
The Go Programming Language Specification Version of July 31,
2019
A "defer" statement invokes a function whose execution is deferred to
the moment the surrounding function returns, either because the
surrounding function executed a return statement, reached the end of
its function body, or because the corresponding goroutine is
panicking.
你写:
set_char := C.cmalloc(0)
static char** cmalloc(int size) {
return (char**) malloc(size * sizeof(char*));
}
$ man malloc
The malloc() function allocates size bytes and returns a pointer to
the
allocated memory. The memory is not initialized. If size is 0, then
malloc() returns either NULL, or a unique pointer value that can later
be successfully passed to free().
为什么分配大小 0(零)?
malloc
内存未初始化。
我终于可以 return 使用 cgo
从 GO
得到 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()
。否则,它将在 returning 之后被释放。
我必须从 Java 调用 Go 函数。
我正在使用 cgo
和 JNA
来执行此操作。
Go 例程所做的唯一事情就是分配内存和 return char**
。从 Java 方面,我正在使用 String[]
接收 char**
,如 documentation 中所述。
以下是 C helper 和 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 中 returning a []string
?
由于打字错误和基于@PeterSO 回答的更新:
- 我最初写的是 malloc(0) 但它应该是 malloc(1)
func C.CString(string) *C.char
,它应该给我分配内存,是 不是吗?
你写:
func getSearchKeysA() **C.char {
set_char := C.cmalloc(0)
defer C.free(unsafe.Pointer(set_char))
C.setElement(set_char, C.CString("hello world"), C.int(0))
return set_char
}
可能执行为:
func getSearchKeysA() (retval **C.char) {
set_char := C.cmalloc(42)
C.setElement(set_char, C.CString("hello world"), C.int(1))
retval = set_char
C.free(unsafe.Pointer(set_char))
return retval
}
你指的是 free
之后的 set_char
吗?
The Go Programming Language Specification Version of July 31, 2019
A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.
你写:
set_char := C.cmalloc(0)
static char** cmalloc(int size) {
return (char**) malloc(size * sizeof(char*));
}
$ man malloc
The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
为什么分配大小 0(零)?
malloc
内存未初始化。
我终于可以 return 使用 cgo
从 GO
得到 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()
。否则,它将在 returning 之后被释放。