我正在尝试使用 Go 构建示例共享对象库。代码编译(使用命令 go build -o libsample.so -buildmode=c-shared .),一个共享对象库被成功构建 - 但同时通过 JNA(来自 Java)访问导出的方法或 ctypes(来自 python),我很 panic 。
我用 Go 写的代码是:
// package name: libsample.so
package main
import "C"
import "fmt"
//export Hello
func Hello(s string) {
fmt.Println("Hello " + s + "!")
}
func main() {
}
从 Java 访问此方法 Hello 时:
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/python
import ctypes
lib = ctypes.CDLL("./libsample.so")
lib.Hello("World")
我收到以下错误:
runtime: out of memory: cannot allocate 140042998120448-byte block (1048576 in use)
fatal error: out of memory
runtime stack:
runtime.throw(0x7f5e434bfe50, 0xd)
/usr/local/go/src/runtime/panic.go:530 +0x92
runtime.largeAlloc(0x7f5e4d27dc8d, 0xc800000003, 0xc82003cf08)
/usr/local/go/src/runtime/malloc.go:768 +0xdf
runtime.mallocgc.func3()
/usr/local/go/src/runtime/malloc.go:664 +0x35
runtime.systemstack(0x7f5e4e4d3ab8)
/usr/local/go/src/runtime/asm_amd64.s:291 +0x72
runtime.mstart()
/usr/local/go/src/runtime/proc.go:1048
goroutine 17 [running, locked to thread]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:245 fp=0xc82003cb50 sp=0xc82003cb48
runtime.mallocgc(0x7f5e4d27dc8d, 0x0, 0x3, 0x0)
/usr/local/go/src/runtime/malloc.go:665 +0x9fe fp=0xc82003cc28 sp=0xc82003cb50
runtime.rawstring(0x7f5e4d27dc8d, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/runtime/string.go:284 +0x72 fp=0xc82003cc70 sp=0xc82003cc28
runtime.rawstringtmp(0x0, 0x7f5e4d27dc8d, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/runtime/string.go:111 +0xb9 fp=0xc82003cca8 sp=0xc82003cc70
runtime.concatstrings(0x0, 0xc82003ce38, 0x3, 0x3, 0x0, 0x0)
/usr/local/go/src/runtime/string.go:49 +0x1bf fp=0xc82003cde0 sp=0xc82003cca8
runtime.concatstring3(0x0, 0x7f5e434ba9d0, 0x6, 0x7f5e48155490, 0x7f5e4d27dc86, 0x7f5e434ba560, 0x1, 0x0, 0x0)
/usr/local/go/src/runtime/string.go:63 +0x6c fp=0xc82003ce30 sp=0xc82003cde0
main.Hello(0x7f5e48155490, 0x7f5e4d27dc86)
/home/vagrant/go/src/github.com/venkatramachandran/lib-sample/sample.go:9 +0x72 fp=0xc82003cec8 sp=0xc82003ce30
main._cgoexpwrap_9f7405a93e67_Hello(0x7f5e48155490, 0x7f5e4d27dc86)
github.com/venkatramachandran/lib-sample/_obj/_cgo_gotypes.go:48 +0x2d fp=0xc82003cee0 sp=0xc82003cec8
runtime.call32(0x0, 0x7f5e4e4d3ae8, 0x7f5e4e4d3b70, 0x10)
/usr/local/go/src/runtime/asm_amd64.s:472 +0x40 fp=0xc82003cf08 sp=0xc82003cee0
runtime.cgocallbackg1()
/usr/local/go/src/runtime/cgocall.go:267 +0x110 fp=0xc82003cf40 sp=0xc82003cf08
runtime.cgocallbackg()
/usr/local/go/src/runtime/cgocall.go:180 +0xd9 fp=0xc82003cfa0 sp=0xc82003cf40
runtime.cgocallback_gofunc(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:716 +0x5d fp=0xc82003cfb0 sp=0xc82003cfa0
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1998 +0x1 fp=0xc82003cfb8 sp=0xc82003cfb0
goroutine 18 [syscall, locked to thread]:
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1998 +0x1
Aborted (core dumped)
出了什么问题?如果我使用 int 或 float 作为参数创建方法,则不会发生此错误。
最佳答案
原因:
这背后的原因是你的 go 函数 Hello 需要一个 golang 字符串,但是 python 和 Java 传递了 C 风格 字符串。
解决方案:
因为您已经使用 buildmode=c-shared 编译了您的 golang 库。 Python ctypes 包和 java JNI 将其视为普通的 c 方法。并传递一个 c 风格的字符串,它实际上只是一个以 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() {
}
关于go - 从共享库访问函数时出现内存不足 panic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36482970/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file