为了账号安全,请及时绑定邮箱和手机立即绑定

使用 cgo 从 Go 返回 String[]

使用 cgo 从 Go 返回 String[]

Go
慕勒3428872 2023-08-14 16:51:06
我必须从 Java 调用 Go 函数。我正在使用cgo和JNA来执行此操作。Go 例程所做的唯一事情就是分配内存并返回一个char**. 从Java方面,我收到了文档中提到的char**使用。String[]以下是 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 getSearchKeysAfunc 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))错误的原因可能是什么以及如何解决?还有其他方法可以[]string使用 Go 从 Go返回 a 吗JNA?由于拼写错误并基于 @PeterSO 答案进行更新:我最初写的是malloc(0),但应该是malloc(1)func C.CString(string) *C.char,它应该为我分配内存,不是吗?
查看完整描述

2 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

我终于可以String[]从GO使用中返回 a 了cgo。


我将留下函数签名:


//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我收到的数据如下:


IntByReference intByReference = new IntByReference();

PointerByReference array = lib.getSearchKeys(intByReference);

String[] results = array.getPointer().getStringArray(0, intByReference.getValue());

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


查看完整回答
反对 回复 2023-08-14
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

你写:


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

}

你指的是set_char之后吗free


Go 编程语言规范2019 年 7 月 31 日版本

推迟陈述

“defer”语句调用一个函数,该函数的执行被推迟到周围函数返回的那一刻,要么是因为周围函数执行了 return 语句,到达了其函数体的末尾,要么是因为相应的 goroutine 正在恐慌。


你写:

set_char := C.cmalloc(0)
static char** cmalloc(int size) {
    return (char**) malloc(size * sizeof(char*));
}

$ 人 malloc

malloc() 函数分配 size 字节并返回指向所分配内存的指针。内存未初始化。如果 size 为 0,则 malloc() 返回 NULL,或稍后可以成功传递给 free() 的唯一指针值。

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

malloc内存未初始化。


查看完整回答
反对 回复 2023-08-14
  • 2 回答
  • 0 关注
  • 172 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信