使用 Libdl.dlopen 杀死 Julia
Posted
技术标签:
【中文标题】使用 Libdl.dlopen 杀死 Julia【英文标题】:Using Libdl.dlopen kills Julia 【发布时间】:2018-03-03 13:52:04 【问题描述】:我正在尝试从 Julia v0.6.2、Windows 10 调用 C 代码。
这是我用Cygwin gcc 编译成 DLL 的 C 代码。
int timesTwo(int x)
return 2*x;
编译命令:
gcc -c mydll.c
gcc -shared -o mydll.dll mydll.o
我用测试 C 程序测试了 DLL,它可以工作。然后我尝试使用 DLL 的绝对路径与 Julia 一起调用它。
using Base.Libdl
x = Int32(2)
mylib = dlopen("C:\\Users\\pedro\\Documents\\codigos\\exampleDLL\\C\\mydll.dll")
ccall((:timesTwo, mylib), Int32, (Int32,), x)
然后重新启动 Julia 的工作区(一旦我使用命令 dlopen
,所有变量都将变为未定义)。
发生了什么,我该如何解决?
更新
那一定是windows的问题。无法在 Ubuntu 发行版中重现。
【问题讨论】:
也许您应该添加-fPIC
标志并重试。
int double( int x )...
甚至编译?!?! double
is a reserved word.
实际函数名为ddouble
。将其更改为 timesTwo
以避免歧义。
【参考方案1】:
我会尝试使用与 Julia 相同的编译器(带有 -fPIC 标志)来构建您的 DLL。在 Windows 上,Julia 实际上是用 Cygwin 到 MinGW 的交叉编译器:
https://github.com/JuliaLang/julia/blob/master/README.windows.md#cygwin-to-mingw-cross-compiling
您能否安装 mingw64-x86_64-gcc-core 包(仅用于 C 编译器)并使用 x86_64-w64-mingw32-gcc 编译器命令(而不是 gcc)?
【讨论】:
【参考方案2】:使用-fPIC
开关生成与位置无关的代码。另外,您可能对Julia
撒谎,除非您的int
在特定平台上定义为int32
。可以肯定的是,您需要将ccall((:timesTwo, mylib), Int32, (Int32,), x)
更改为ccall((:timesTwo, mylib), Cint, (Cint,), x)
。最后,为了使代码适用于任何操作系统,请考虑将mylib = dlopen("C:\\Users\\pedro\\Documents\\codigos\\exampleDLL\\C\\mydll.dll")
替换为const mylib = dlopen(joinpath(pwd(), "mydll.dll"))
。 const
是出于效率原因,joinpath
与操作系统无关,这意味着它将为基于 *nix 的系统添加正斜杠。稍后,当你想将库更改为.so
时,你也不应该处理斜线。
【讨论】:
以上是关于使用 Libdl.dlopen 杀死 Julia的主要内容,如果未能解决你的问题,请参考以下文章