首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用cgo从Go返回String[]

使用cgo从Go返回String[]
EN

Stack Overflow用户
提问于 2019-12-27 04:11:27
回答 2查看 582关注 0票数 1

我必须从Java调用Go函数。我正在使用cgoJNA来完成这个任务。

Go例程所做的唯一事情就是分配内存并返回一个char**。在Java方面,我正在使用char**接收String[],就像文档中提到的那样。

下面是C助手和Go函数的详细信息:

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

代码语言:javascript
复制
String[] getSearchKeysA();

我得到的错误是:

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

造成错误的原因是什么,我如何解决呢?还有其他方法从Go使用[]string返回JNA吗?

由于输入错误而更新,并以@PeterSO为基础回答:

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-27 19:30:28

我最终可以使用String[]GO返回cgo

我将留下功能签名:

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

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

代码语言:javascript
复制
IntByReference intByReference = new IntByReference();
PointerByReference array = lib.getSearchKeys(intByReference);
String[] results = array.getPointer().getStringArray(0, intByReference.getValue());

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

票数 1
EN

Stack Overflow用户

发布于 2019-12-27 05:35:07

你写:

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

它很可能以下列方式执行:

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

你是指set_char之后的free吗?

2019年7月31日的Go程序设计语言规范版本 延迟陈述 一个“延迟”语句调用一个函数,其执行被推迟到周围函数返回的那一刻,因为周围的函数执行了一个返回语句,到达了它的函数体的末尾,或者因为相应的goroutine在恐慌。

你写:

代码语言:javascript
复制
set_char := C.cmalloc(0)

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

$ man malloc 函数分配大小字节并返回指向分配内存的指针。内存未初始化。如果大小为0,那么malloc()将返回NULL,或者返回一个以后可以成功传递给free()的唯一指针值。

为什么分配0(0)大小?

malloc内存未初始化。

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

https://stackoverflow.com/questions/59495888

复制
相关文章

相似问题

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