Articles of dynamic

Python的ctypes不加载在Mac OS X的dynamic库

我有一个C ++库repeater.so ,我可以在Linux中从Python加载以下方式: import numpy as np repeater = np.ctypeslib.load_library('librepeater.so', '.') 但是,当我在Mac OS X(Snow Leopard,32位)上编译相同的库并获得repeater.dylib ,然后在Python中运行以下代码: import numpy as np repeater = np.ctypeslib.load_library('librepeater.dylib', '.') 我得到以下错误: OSError: dlopen(/mydir/librepeater.dylib, 6): no suitable image found. Did find: /mydir/librepeater.dylib: mach-o, but wrong architecture 在Mac OS X上,我是否需要做一些不同的工作才能在Python中加载dynamic库?

在Linux上创build.SO文件而不使用PIC(位置独立代码)(x86 32位)

据我所知,x86汇编代码受寄存器数量有限的限制。 当我在Linux上得知,为了创build一个.so文件,我们必须为gcc指定-fPIC命令行参数来创build与位置无关的代码,我不能相信它。 据我所知,elf文件格式支持重定位,就像在我眼中好得多 – Windows DLL系统工作:在Windows上,链接器重新定位DLL中的所有偏移(如果需要的话)。 我认为加载SO文件或DLL文件所需的时间,以及用于保存不同的.so文件的内存量并没有像指向整个寄存器的时间一样糟糕GOT和所有这些间接跳跃。 我也不在乎ALSR等等,因为我只是关心在库中的代码尽可能优化。 1)为什么Linux不支持更多的dynamic库加载,如Windows应该产生更多的性能代码? 到目前为止,我没有find真正的解释。 只是有些事情,如果重定位代码会非常糟糕,速度太慢(当然,在桌面计算机上加载文字处理器,加载速度有多快,我完全接受,但是对于计算密集型服务器进程不处理来自互联网的恶意数据),我想拥有所有的性能和注册我可以得到! 2)是否可以在Linux上创build非-fPIC编译的SO文件? 我可以离开-fPIC吗? 有没有什么howto,手册或项目在这个主题上工作,并可以不浪费整个注册,并仍然dynamic加载库? 如果我在编译.so文件时只放下-fPIC会怎么样?

linux交叉编译和dynamic库/链接

我正在努力为BeagleBoard开发。 因此我安装了CodeSourcery Sourcery_G ++ _ Lite工具链。 我想使用opencv库。 所以我把源代码下载到我的Ubuntu devolepment系统中,用gcc作为共享库编译并安装了这个库。 当我为x86架构构build一个helloworld应用程序时,一切都很好。 现在,我想用ARM架构的其他工具链编译相同的应用程序。 编译/链接时,我得到这些警告/错误: john@ubuntu:~/Downloads/BeagleTest$ arm-none-linux-gnueabi-g++ -c ImageProcessing.cpp -o ImageProcessing.o -I/usr/local/include cc1plus: warning: include location "/usr/local/include" is unsafe for cross-compilation john@ubuntu:~/Downloads/BeagleTest$ arm-none-linux-gnueabi-g++ -c Main.cpp -o Main.o -I/usr/local/include cc1plus: warning: include location "/usr/local/include" is unsafe for cross-compilation john@ubuntu:~/Downloads/BeagleTest$ arm-none-linux-gnueabi-g++ -oApplication -L/usr/local/lib Main.o ImageProcessing.o -lopencv_core /usr/local/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/arm-none-linux-gnueabi/4.2.1/../../../../arm-none-linux-gnueabi/bin/ld: warning: library search […]

将代码/符号修补为dynamic链接的ELF二进制文件

假设我有一个dynamic链接的ELF二进制文件,我想覆盖/redirect某些库调用。 我知道我可以用LD_PRELOAD来做到这一点,但是我想要一个在二进制文件中永久存在的独立于环境的解决scheme,它可以用于setuid / setgid二进制文件,其中没有一个是LD_PRELOAD可以实现的。 我想要做的就是从其他目标文件中添加代码(如有必要,可能在新的部分添加代码),并将这些目标文件中的符号添加到二进制文件的符号表中,这样就可以使用新添加的代码版本代替共享库代码。 我相信这应该是可能的,而不需要在现有的代码中进行实际的迁移。 即使它们在同一个文件中,它们应该能够在运行时以通常的PLT方式来parsing(因为我只关心函数,而不关心数据)。 请不要给我答复,“你不想这样做!” 或者“那不是便携的!” 我正在处理的是一种连接二进制文件与ABI不兼容的备用共享库实现的方式。 有问题的平台是i386-linux(即32位)。 除非我误解了什么是可能的,否则我可以编写一些工具来parsingELF文件并执行我的黑客攻击,但我怀疑有一种奇怪的方式来使用GNU链接器和其他工具来完成此操作,而无需编写新代码。

dlopen vs连接开销

假设我有一个库–foo.so。 在构build我的二进制文件(需要这个库)时,我可以(1)链接foo.so,或者(2)在程序源代码中,dlopen这个库,然后调用这个库提供的函数 当我从库中调用函数时,(1)和(2)之间是否有任何性能差异? 请注意,我知道会有不同的初始化特性(如dlopen的开销,第一次使用符号的开销等),但是在稳定状态下,两种select都同样快,还是更快? 谢谢。

在dynamic加载共享库时获取未定义的符号错误

dynamic加载库时遇到undefined symbol错误。 这是我的代码片断,产生这个错误: int main () { void *lib_handle = NULL; MyClass* (*create)(); void (*destroy)(MyClass*); char *error; lib_handle = dlopen ("./libshared.so", RTLD_LAZY); if (lib_handle == NULL) { fprintf(stderr, "%s\n", dlerror()); exit(1); } create = (MyClass* (*)()) dlsym(lib_handle, "create_object"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(1); } destroy = (void (*)(MyClass*)) dlsym(lib_handle, […]

Linux不能finddynamic链接的应用程序

我有一个运行Linux Kernel 3.10和Busybox的embedded式系统。 如果我交叉编译(通过buildroot构build工具链,所以它使用uclibc)一个没有-static标志的程序。 它不会运行。 -/bin/sh: helloworld: not found 如果我用-static标志编译我的代码。 它通常会运行并输出HelloWorld 这里发生了什么?

C ++ linux:dlopen无法find.so库

重写的问题(虽然已经解决了): 我一直在使用dlopen(3)在Linux上加载共享库。 这个库是由我构build的一个库系统的一部分,它们都是在运行时由中央可执行文件加载的。 所有这些都在Code :: Blocks中组织成一个工作区,每个项目在一个名为Source的目录中都有自己的文件夹,这个目录将随程序一起提供。 可执行文件的构build目录是两个从它自己的源代码向后的目录,所以exectuable和Source文件夹在同一个目录中,这些库也和可执行文件一样构build到同一个目录,所以自然我就传递了这个库的名字我试图打开如图所示: int main(int argc, char** argv) { void* hLibrary = dlopen("libLibrary.so", RTLD_NOW | RTLD_GLOBAL); if(hLibrary == NULL) { fprintf(stderr, "%s\n", dlerror()); return 1; } return 0; } 当构build目录与源代码相同时,这一点起作用,直到我将源代码的目录改变为上述安排。 现在的问题是dlerror()返回“无法打开libLibrary.so:没有这样的文件或目录”,即使该文件明显存在并且与可执行文件在同一目录中。 然后我尝试传入“/libLibrary.so”,因为根据dlopen(3)上的手册页,添加/表示相对目录。 这返回了同样的错误。 解决这个问题的方法是需要一个“./” – “”。 表示可执行文件的工作目录 – 并且需要在Code :: Blocks中将工作目录更改为可执行文件的构build目录。 以下作品完美: void* hLibrary = dlopen("./libLibrary.so", RTLD_NOW | RTLD_GLOBAL); 这并不能真正显示完整的解决scheme,但以下基本上与我正在做的事情相同: void* […]

dynamic加载和弱符号分辨率

分析这个问题,我发现了一些关于Linux上dynamic加载( dlopen )的情况下弱符号parsing的行为。 现在我正在寻找这个规范。 我们来举个例子 。 假设有一个程序a按顺序dynamic加载库b.so和c.so 如果c.so依赖于另外两个库foo.so (实际上是libgcc.so )和bar.so (实际上是libpthread.so ),那么通常由bar.so导出的bar.so可以用来满足foo.so弱符号链接foo.so 。 但如果b.so也取决于foo.so而不是bar.so ,那么这些弱符号显然不会与bar.so 。 似乎foo.so只能查找a和b.so及其所有依赖的符号。 这在某种程度上是有道理的,否则加载c.so可能会改变foo.so在b.so已经使用库的某个点上的行为。 另一方面,在我这个问题上,这个问题引起了很多麻烦,所以我想知道是否有办法解决这个问题。 为了find解决办法,我首先需要很好地了解如何在这些情况下指定符号parsing的具体细节。 什么是规范或其他技术文件来定义在这些情况下的正确行为?

如何从共享库调用函数?

从共享库/ DLL调用函数最简单和最安全的方法是什么? 我最感兴趣的是在linux上这样做,但如果有一个平台无关的方式会更好。 有人可以提供示例代码来展示如何进行以下工作,用户将自己的foo版本编译到共享库中? // function prototype, implementation loaded at runtime: std::string foo(const std::string); int main(int argc, char** argv) { LoadLibrary(argv[1]); // loads library implementing foo std::cout << "Result: " << foo("test"); return 0; } 顺便说一句,我知道如何编译共享库( foo.so ),我只需要知道一个简单的方法来加载它在运行时。