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

从共享库访问函数时出现内存不足的恐慌

从共享库访问函数时出现内存不足的恐慌

Go
慕仙森 2022-01-04 10:02:31
我正在尝试使用 Go 构建一个示例共享对象库。代码编译(使用命令go build -o libsample.so -buildmode=c-shared .),成功构建了一个共享对象库 - 但是在通过 JNA(来自 Java)或 ctypes(来自 python)访问导出的方法时,我感到恐慌。我用 Go 写的代码是:// package name: libsample.sopackage mainimport "C"import "fmt"//export Hellofunc Hello(s string) {    fmt.Println("Hello " + s + "!")}func main() {}Hello从 Java访问此方法时:import com.sun.jna.*;public class sample {    public interface GoSO extends Library {        GoSO INSTANCE = (GoSO) Native.loadLibrary("sample" ,GoSO.class);        void Hello(String s);    }    public static void main(String[] args) {        GoSO.INSTANCE.Hello("World");    }}或来自 Python:#!/usr/bin/pythonimport ctypeslib = ctypes.CDLL("./libsample.so")lib.Hello("World")我收到以下错误:runtime: out of memory: cannot allocate 140042998120448-byte block (1048576 in use)fatal error: out of memoryruntime stack:runtime.throw(0x7f5e434bfe50, 0xd)    /usr/local/go/src/runtime/panic.go:530 +0x92runtime.largeAlloc(0x7f5e4d27dc8d, 0xc800000003, 0xc82003cf08)    /usr/local/go/src/runtime/malloc.go:768 +0xdfruntime.mallocgc.func3()    /usr/local/go/src/runtime/malloc.go:664 +0x35runtime.systemstack(0x7f5e4e4d3ab8)    /usr/local/go/src/runtime/asm_amd64.s:291 +0x72runtime.mstart()    /usr/local/go/src/runtime/proc.go:1048goroutine 17 [running, locked to thread]:runtime.systemstack_switch()    /usr/local/go/src/runtime/asm_amd64.s:245 fp=0xc82003cb50 sp=0xc82003cb48runtime.mallocgc(0x7f5e4d27dc8d, 0x0, 0x3, 0x0)    /usr/local/go/src/runtime/malloc.go:665 +0x9fe fp=0xc82003cc28 sp=0xc82003cb50runtime.rawstring(0x7f5e4d27dc8d, 0x0, 0x0, 0x0, 0x0, 0x0)    /usr/local/go/src/runtime/string.go:284 +0x72 fp=0xc82003cc70 sp=0xc82003cc28runtime.rawstringtmp(0x0, 0x7f5e4d27dc8d, 0x0, 0x0, 0x0, 0x0, 0x0)出了什么问题?如果我使用 anint或 afloat作为参数创建方法,则不会发生此错误。
查看完整描述

1 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

原因: 这背后的原因是你的 go 函数Hello需要一个golang字符串,但是 python 和 Java 传递了C style字符串。


解决方案: 由于您已经使用buildmode=c-shared. Pythonctypes包和 java JNI 将其视为简单的 c 方法。并传递 ac 样式字符串,它实际上只是一个以NULL.


但是在您的代码中,函数Hello需要一个 golang 字符串,它的格式与典型的 c 样式字符串不同。因此出现此错误。


可以通过声明s为来解决*C.char。


修正后的程序如下:


// package name: libsample.so

package main


import "C"

import "fmt"


//export Hello

func Hello(s *C.char) {

    fmt.Println("Hello " + C.GoString(s) + "!")

}


func main() {

}


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 285 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号