我链接两个不同的共享库.两个库都定义了一些共享名称但具有不同实现的符号.我不能让每个库使用自己的实现而不是另一个.
例如,两个库都定义了一个bar()内部调用的全局函数.库1调用它foo1(),库2调用它foo2().
Lib1.so:
T bar
T foo1() // calls bar()
Run Code Online (Sandbox Code Playgroud)
Lib2.so:
T bar
T foo2() // calls bar()
Run Code Online (Sandbox Code Playgroud)
如果我将我的应用程序链接到Lib1.so然后链接到Lib2.so即使在调用时也会调用Lib1.so中的bar实现foo2().另一方面,如果我将我的应用程序链接到Lib2.so然后链接到Lib1.so,则始终从Lib2.so调用bar.
有没有办法让库总是更喜欢自己的实现高于任何其他库?
我正在尝试从Haskell源代码创建一个共享库.
我试过按照这里的说明:http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/但我没有运气.
当我使用Haskell 64位(2011.4.0.0中的ghc 7.0.4)编译时,我收到以下错误:
ld: pointer in read-only segment not allowed in slidable image, used in
___gmpn_modexact_1c_odd
Run Code Online (Sandbox Code Playgroud)
作为替代方案,我也尝试了32位版本,并根据我用来链接获取错误的确切标志,例如:
Library not loaded: /usr/local/lib/ghc-7.0.4/base-4.3.1.0/libHSbase-4.3.1.0-ghc7.0.4.dylib
Run Code Online (Sandbox Code Playgroud)
通过将-lHSrts添加到链接器行,我确实设法得到了更多.这让我成功地链接和加载库,但我无法使用dlsym找到函数名称(或者手动使用nm | grep)
任何提示将不胜感激,一个示例生成文件,或成功构建(和使用)OS X上的共享库的构建行将不胜感激.我对Haskell很新,并且不知道我是否应该继续敲打我的脑袋,假设问题出现在我的最后,或者出于各种原因我不应该期望这在OS X上工作.
我尝试过的所有组合的git repo都可以在这里找到:https://github.com/bennoleslie/haskell-shared-example我确实设法为32位ghc工作,但不是64位.
我想在Haskell项目中使用外部库RDFox.
上下文:我使用GHC 7.10和堆栈在64位上运行Windows和Linux .RDFox是用C++编程的.可以使用Java和Python包装器下载RDFox共享库(.dll,.so).
目的:我想在我的Haskell项目中重用RDFox(.dll,.so)中的编译库,因此我需要为RDFox创建一个Haskell包装器.
问题:对于Haskell来说相对较新,我很难知道从哪里开始.我找到了几个关于这个主题的页面(来自Haskell wiki和StackOverflow),但工作流程和配置对我来说并不清楚.
问题:我想知道:
- 如何配置堆栈和cabal以使用外部库,在Windows 或 Linux(不同的机器,相同的存储库)上构建.
- 如何在此外部库上配置GHCi以进行交互式测试.
- 将Python包装器转换为Haskell是最好的方法吗?我想避免分析RDFox C++代码.
我有一个共享库,我希望链接可执行文件与使用GCC.共享库具有非标准名称,而不是libNAME.so形式,因此我不能使用通常的-l选项.(它恰好也是一个Python扩展,因此没有'lib'前缀.)
我能够将库文件的路径直接传递给链接命令行,但这会导致库路径硬编码到可执行文件中.
例如:
g++ -o build/bin/myapp build/bin/_mylib.so
Run Code Online (Sandbox Code Playgroud)
有没有办法链接到这个库而不会导致路径被硬编码到可执行文件中?
我想在编译时在Mac OSX下设置可执行文件的运行时路径(对于链接器),这样在程序启动时动态链接器可以找到非标准位置的共享库.
在Linux下,可以使用-Xlinker -rpath -Xlinker /path/to(或使用-Wl,-rpath,/path/to),在Solaris下,您可以添加-R/path/to到编译器命令行.
我发现一些信息,Mac OS X gcc自10.5以来就支持-rpath,即自2008年以来.
我尝试用最小的例子来实现它 - 没有成功:
$ cat blah.c
int blah(int b)
{
return b+1;
}
Run Code Online (Sandbox Code Playgroud)
和:
$ cat main.c
#include <stdio.h>
int blah(int);
int main ()
{
printf("%d\n", blah(22));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译它像这样:
$ gcc -c blah.c
$ gcc -dynamiclib blah.o -o libblah.dylib
$ gcc main.c -lblah -L`pwd` -Xlinker -rpath -Xlinker `pwd`/t
Run Code Online (Sandbox Code Playgroud)
现在测试:
$ mkdir t
$ mv libblah.dylib t
$ ./a.out
dyld: Library …Run Code Online (Sandbox Code Playgroud) 在Windows中加载共享库时,LoadLibrary()调用库中的原因DllMain,以便为每个新进程和线程库附加,以及为每个进程和线程库执行detaaches.
Mac OS X,Linux和其他POSIX兼容的操作系统是否有类似的机制?
我有一些使用一些共享库的代码(gcc上的c代码).编译时我必须使用-I和-L显式定义include和library目录,因为它们不在标准位置.当我尝试运行代码时,出现以下错误:
./sync_test
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
但是,执行以下操作,一切正常:
export LD_LIBRARY_PATH="/path/to/library/"
./sync_test
Run Code Online (Sandbox Code Playgroud)
现在,奇怪的是,这只能工作一次.如果我再次尝试运行sync_test,除非我先运行export命令,否则会得到相同的错误.我尝试将以下内容添加到我的.bashrc中,但它没有区别:
LD_LIBRARY_PATH="/path/to/library/"
Run Code Online (Sandbox Code Playgroud) 这是一个绝望的问题,因为我搜索了文档和Fiddle的代码,发现没有关于嵌套结构的线索(尽管FFI库能够做到这一点,而Fiddle应该是FFI的包装器).
我的问题如下:
何时是程序中指定的共享对象的地址?链接期间?数据加载中?如果我想在程序system内部找到命令的内存地址,libc我可以很容易地找到它gdb,但是如果我不想将程序带入调试器呢?
这个地址可以从一次运行变为运行吗?是否还有其他静态分析工具可以查看运行时将库或函数加载到该程序的内存空间的位置?
编辑:我想在程序之外的这些信息(即使用实用程序,如objdump收集信息)
究竟是什么-rdynamic(或--export-dynamic在链接器级别)做什么以及它如何与由-fvisibility*标志或可见性pragmas和__attribute__s 定义的符号可见性相关?
对于--export-dynamic,ld(1)提到:
...如果使用"dlopen"加载需要引用程序定义的符号的动态对象,而不是某些其他动态对象,则在链接程序本身时可能需要使用此选项....
我不确定我完全明白这一点.能否请您提供一个例子,如果没有它可以工作-rdynamic但是没有它?
编辑:我实际上尝试编译了几个虚拟库(单个文件,多个文件,各种-O级别,一些函数间调用,一些隐藏符号,一些可见),有和没有-rdynamic,到目前为止我一直在字节相同的输出(当然保持所有其他标志不变),这是非常令人费解的.