您好,我将在 Linux 环境中使用带有 golang 的第三方库(.so 文件)。所以我试着用一些微不足道的东西来练习一下,比如从 linux 原生库中导入函数。并卡在导入和调用 sqrt 函数上。这是我的代码:
package main
// #cgo LDFLAGS: -ldl
// #include <dlfcn.h>
// #include <stdio.h>
import "C"
import "fmt"
func main() {
export_name := "sqrt"
lib_path := "/lib/libm.so.6"
//Loading .so
handle := C.dlopen(C.CString(lib_path), C.RTLD_LAZY)
if handle == nil {
fmt.Println(lib_path+":\tNOT FOUND")
return
} else {
fmt.Println(lib_path+":\tSUCCESS")
}
//looking for function address
func_pointer := C.dlsym(handle, C.CString(export_name ))
if func_pointer == nil {
fmt.Println(export_name+":\tNOT FOUND")
return
} else {
fmt.Println(export_name+":\t", func_pointer)
}
//negotiating datatypes
//From c lib description: double sqrt(double x);
sqrt := *(*(func(float64)float64))(func_pointer)
//Calling function
sqrt(4)
}
当我运行它时,我总是遇到分段冲突:
/lib/libm.so.6: SUCCESS
sqrt: 0x7f37117ea270
unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x4019fa]
goroutine 1 [running]:
runtime.throw(0x4a6643, 0x5)
/usr/lib/go/src/runtime/panic.go:566 +0x95 fp=0xc42004be00 sp=0xc42004bde0
runtime.sigpanic()
/usr/lib/go/src/runtime/sigpanic_unix.go:27 +0x288 fp=0xc42004be58 sp=0xc42004be00
main.main()
/home/afx/goc/so.go:37 +0x2ba fp=0xc42004bf48 sp=0xc42004be58
runtime.main()
/usr/lib/go/src/runtime/proc.go:183 +0x1f4 fp=0xc42004bfa0 sp=0xc42004bf48
runtime.goexit()
/usr/lib/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc42004bfa8 sp=0xc42004bfa0
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/lib/go/src/runtime/asm_amd64.s:2086 +0x1
exit status 2
问题是什么? 提前谢谢你。
附言 当我重新定义 native Go 函数的函数指针时(如此处 Go: convert unsafe.Pointer to function pointer and vice versa ),一切正常。但是导入失败。
最佳答案
这是解决方案。我不得不使用桥接 C 函数:
package main
// #cgo LDFLAGS: -ldl
// #include <dlfcn.h>
// #include <stdio.h>
//
// double
// my_sqrt_bridge(void *f, double x)
// {
// //description: ((return_data_type (*)(input_data_type))bridge_input_function_pointer) (bridge_input_value)
// return ((double (*)(double))f)(x);
// }
import "C"
import "fmt"
func main() {
export_name := "sqrt"
lib_path := "/lib/libm.so.6"
//Loading .so
handle := C.dlopen(C.CString(lib_path), C.RTLD_LAZY)
if handle == nil {
fmt.Println(lib_path + ":\tNOT FOUND")
return
} else {
fmt.Println(lib_path + ":\tSUCCESS")
}
//looking for function address
func_pointer := C.dlsym(handle, C.CString(export_name))
if func_pointer == nil {
fmt.Println(export_name + ":\tNOT FOUND")
return
} else {
fmt.Println(export_name+":\t", func_pointer)
}
fmt.Printf("%f", C.my_sqrt_bridge(func_pointer, 2))
}
关于c - Golang C (.so) 在调用时导入分段违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41328972/
如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否
我正在尝试创建一个与compass一起使用的本地配置文件,这样我们就可以处理开发人员机器上的不同导入路径。到目前为止,我已经尝试将文件导入到异常block中,以防它不存在,然后进一步使用该变量:local_config.rbVENV_FOLDER='venv'config.rbVENV_FOLDER='.'beginrequire'local_config.rb'rescueLoadErrorendputsVENV_FOLDER通常我是一名Python开发人员,所以我希望导入将VENV_FOLDER的值更改为venv,但它仍然是。之后。有没有一种方法可以导入local_config.r
我希望这些值匹配。当shell脚本由于某些错误条件而退出时(因此返回非零值),它们不匹配。壳$?返回1,ruby$?返回256。>>%x[lskkr]ls:kkr:Nosuchfileordirectory=>"">>puts$?256=>nil>>exitHadoop:~Madcap$lskkrls:kkr:NosuchfileordirectoryHadoop:~Madcap$echo$?1 最佳答案 在Ruby中$?是一个Process::Status实例。打印$?等同于调用$?.to_s,这等同于$?.to_i.to_s(来
最好用一个例子来解释:文件1.rb:deffooputs123end文件2.rb:classArequire'file1'endA.new.foo将给出错误“':调用了私有(private)方法'foo'”。我可以通过执行A.new.send("foo")来解决这个问题,但是有没有办法公开导入的方法?编辑:澄清一下,我没有混淆include和require。另外,我不能使用正常包含的原因(正如许多人正确指出的那样)是因为这是元编程设置的一部分。我需要允许用户在运行时添加功能;例如,他可以说“run-this-app--includefile1.rb”,应用程序的行为将根据他在file1
尝试在我的Rails应用程序中导入CSV文件时,出现错误UTF-8中的无效字节序列。一切正常,直到我添加了一个gsub方法来将其中一个CSV列与我的数据库中的一个字段进行比较。当我导入CSV文件时,我想检查每一行的地址是否包含在特定客户端的不同地址数组中。我有一个带有alt_addresses属性的客户端模型,其中包含客户端地址的几种不同可能格式。然后我有一个引用模型(如果您熟悉本地SEO,您就会知道这个术语)。引用模型没有地址字段,但它有一个nap_correct?字段(NAP代表“姓名”、“地址”、“电话号码”)。如果CSV行的名称、地址和电话号码与我在该客户的数据库中拥有的相同,
运行bundle安装时,我收到以下消息:Rubygems2.0.14isnotthreadsafe,soyourgemswillbeinstalledoneatatime.UpgradetoRubygems2.1.0orhighertoenableparallelgeminstallation.这很奇怪,因为在我的RubyGems环境中它说我的RubyGems版本是:2.4.5.1(见下文)~/w/Rafftopia❯❯❯gemenvRubyGemsEnvironment:-RUBYGEMSVERSION:2.4.5.1-RUBYVERSION:2.2.5(2016-04-26patc
我正在尝试编写一个Ruby扩展,而且我一整天都在成功编译我的nmatrix.so共享对象文件。但是,突然之间,它开始生成nmatrix.bundle,而根本没有任何.so文件。它没有给我任何链接器错误,所以我无法想象为什么会这样。我也没有更改myMakefileorextconf.rb中的任何内容.我一直通过rvm使用Ruby1.9.3p0。我已经尝试对当天的工作执行gitstashsave并编译一些我知道应该没有链接器错误的东西(产生.so的东西)更早。不幸的是,这也会生成一个.bundle文件。很明显,我做了一些事情——可能是无意中安装了一些东西——这改变了一些关键的GCC设置。这
我正在关注SyntaxHighlightingRevised的RailsCasts剧集.我将我的ApplicationHelper更新为如下所示:require'redcarpet'moduleApplicationHelperclassHTMLwithPygments但是,我的网络应用返回RoutingErroruninitializedconstantRedcarpet::RenderTryrunningrakeroutesformoreinformationonavailableroutes.我使用的是Rails3.2.11,Redcarpet在Rails控制台中响应良好。我最初
我正在对用户的提要进行分页,并想模拟我正在使用的API的响应。API可以返回奇怪的结果,所以我想确保如果API返回我已经看到的项目,请停止分页。我使用minitest在第一次调用方法get_next_page时stub,但我想在第二次和第三次用不同的值调用它时stub。我应该只使用rSpec吗?ruby新手...这是片段test"crawlerdoesnotpaginateifnonewitemsinnextpage"do#1:A,B#2:B,D=>D#3:A=>stopcrawler=CrawlJob.newfirst_page=[{"id"=>"item-A"},{"id"=>"i
我在bitbucket上创建了一个私有(private)git存储库并提交了代码。现在我想导出所有(提交、代码、历史记录)并将其导入github上的gitrepo。有没有办法做到这一点?谢谢 最佳答案 在本地检查所有内容到您的计算机和gitpull。创建一个github存储库将此存储库添加为您的第二个远程(“使用gitremote添加githubURL”)推送到第二个Remote 关于ruby-git:从bitbucket导出并导入github(带提交),我们在StackOverflow