场景: 可执行文件在运行时通过dlopen加载共享对象。 共享对象引用了一些实际编译到主可执行文件中的符号(一个函数)。 如果在链接可执行文件时向gcc添加-rdynamic,这工作正常。 -rdynamic导出可执行文件的所有非静态符号。 我的共享对象只需要一些select。 问题:有没有办法实现-rdynamic的效果,但是限制了我所知道的共享对象所需的less数select符号? 编辑: 至less有两个人误解了这个问题,所以我试图澄清一下: 这个问题是关于从主可执行文件中导出一个符号的。 这个问题不是从dynamic库中导出符号。 这是一个最小的例子: func.h,通用的头文件 #include <stdio.h> void func(void); main.c,主要可执行代码: #include <dlfcn.h> #include "func.h" // this function is later called by plugin void func(void) { printf("func\n"); } int main() { void * plugin_lib = dlopen("./plugin.so", RTLD_NOW); printf("dlopen -> %p, error: %s\n", plugin_lib, dlerror()); // find and call […]
我创作了一个“共享”另一个共享库(我不是作者/所有者)的共享库, 我的共享库是由一个可执行文件(我不是作者/所有者) 所以层次是:exe dlopen的我的图书馆,我的图书馆dlopen的另一个图书馆。 我的图书馆的图书馆利用openssl。 然而,这个库的作者似乎没有链接openssl库 – 也许假设库的用户会这样做。 因此,当我试图把他们的图书馆,我遇到了未定义的符号错误。 即使我将openssl库链接到我的库,我仍然得到未定义的符号错误。 我的问题是两个: 1)当需要openssl的库被删除时,是否只知道要“查看”exe文件来做符号parsing? 2)有没有特殊的连接器标志,我可能会缺less我的图书馆,链接在openssl,我需要? 谢谢。
在C ++中,可以从dynamic库中访问外部定义的全局variables吗? 我有一个全局variables在头文件中声明如下; 文件名:TestVariable.hpp #ifndef TESTVARIABLE_HPP #define TESTVARIABLE_HPP extern int testVariable; #endif 然后在源代码文件中定义如下: 文件名:TestVariable.cpp int testVariable; 构成我的dynamic库的源代码如下: 文件名:Plugin.cpp #include <TestVariable.hpp> #ifdef __cplusplus extern "C" { #endif void * __attribute__((constructor)) loadLibrary ( void ) { testVariable = 100; } void * __attribute__((destructor)) unloadLibrary ( void ) { } #ifdef __cplusplus } #endif 我的主要function定义如下: 文件名:main.cpp #include <iostream> […]
我在Linux上(Ubuntu 12.04,gcc 4.6.3),尝试弯曲dlopen / close以实现我的意愿,以便制作一个基于插件的应用程序,可以在必要时重新加载插件(例如,如果它们被重新编译) 。 基本理论很简单:插件插件; 使用它,跟踪所有正在使用的符号。 当重新加载的时候,清理所有的符号,并closures插件。 我扔了一个简单的演示程序“test.cpp”: #include <dlfcn.h> #include <iostream> using namespace std; int main(int argc, char** argv) { if (argc > 1) { void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL); if (!h) { cerr << "ERROR: " << dlerror() << endl; return 1; } cin.get(); if (dlclose(h)) { cerr << "ERROR: " […]
我的目标是挂钩在Linux上使用的开放函数。 由于某种原因,这段代码并不是钩住dlopen-> open,而是挂钩了我打开main.c-> open的版本。 dlopen不是以某种方式使用我的符号? 汇编过程如下: gcc main.c -ldl -ggdb gcc fake-open.c -o libexample.so -fPIC -shared export LD_PRELOAD="$PWD/libexample.so" 当我运行程序时,一切正常。 确保LD_PRELOADvariables已设置..等 这里有个问题,当我尝试直接或间接地调用dlopen挂接open函数时,不知何故,这个open的“版本”没有被我的版本解决/redirect/挂钩。 [main.c] #include <dlfcn.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { puts("calling open"); int fd = open("/tmp/test.so", O_RDONLY|O_CLOEXEC); puts("calling dlopen"); int *handle = dlopen("/tmp/test.so", RTLD_LAZY); } [fake-open.c] #define _GNU_SOURCE #include <stdio.h> […]
我的Linux应用程序(A)与我没有源代码的第三方共享库(B)链接。 这个库使用另一个第三方共享库,我没有源代码(C)。 我相信(B)使用dlopen来访问(C)而不是直接链接。 我的推理是,(B)上的“ldd”不显示(C),而objdump -X(B)显示了对dlopen / dlclose / dlsym的引用。 我的要求是,我需要在我的代码(A)获取函数指针函数foo()位于(C)。 通常我会使用dlsym,但是我需要把从dlopen返回的句柄传递给我,因为(B)没有公开这个。 – 对于更大的上下文:我需要修改(C)中的函数,使得每次调用其辅助函数bar()(也位于(C)中)时,它还调用具有与(A) (基本上注入我的代码到(C)foo() – > bar()的代码path。我相信我已经find一种方法来完成这个使用GDB,但为了移植我的GDB命令列表,但我被困在获得函数指针的步骤上,我也愿意select完成相同的任务,而不是像上面所说的那样确切的问题 编辑:在写这个之后,我意识到我可以在我的代码中的文件做另一个dlopen,通过dlsym在该句柄上返回的符号应该是通过原来的dlopen接收相同,如果我正确阅读dlopen手册页。 不过,我仍然对我的大范围内的build议或帮助感兴趣,如果有更好的方法去解决这个问题
getcwd( buff, 1024); 说当前下面的工作path; 我该怎么办? buff = "/home/online0227/my project/Tutorial/Tutorial 1 Device Seletion\0" 我想在Linux上使用下面的函数加载我的.so文件,但是都失败了。 什么是正确的path来描述我的.so文件的path? m_hSO = ::dlopen("..//..//..//..//..//so//myso.so", RTLD_LAZY); if(!m_hSO) { m_hSO = ::dlopen("..//..//..//..//..//so/myso.so", RTLD_LAZY); } if(!m_hSO) { m_hSO = ::dlopen("../../../../../so/myso.so", RTLD_LAZY); } if(!m_hSO) { m_hSO = ::dlopen("..//..//so/myso.so", RTLD_LAZY); }
现在我在linux下编写一个可加载的.so模块,我想在主程序中使用dlopen ,并在可加载的.so模块中使用_init() 。 我的程序是这样的: 主程序: … dlopen(lib, flags); … 可加载模块: #define MODULE_EXPORT(name, minit, mexit) \ int __##name##_init(void) __attribute__((alias(#minit))); \ void __##name##_exit(void) __attribute__((alias(#mexit))); MODULE_EXPORT(dump, dump_init, dump_exit); static int dump_init(void) { … } 现在我想添加参数到dump_init函数中,像这样: static int dump_init(const char *param){} 我不知道如何做到这一点,或者我可以在Linux中使用另一个新的API? 谢谢〜
我有一个Linux应用程序在运行时加载非常小(一些小function)共享库。 对于各种重要原因™,我需要将共享库加载到特定的虚拟内存范围中。 然而, dlopen()并没有提供任何手段(我可以看到)告诉它,或者提示它,在哪里加载它。 有没有办法告诉dlopen()它应该把它加载的库? 有没有其他的dlopen()可以提供这种function?
假设我们有一个非常小的embedded式系统,只包含linux内核和一个静态链接的二进制文件作为init。 我们希望二进制文件能够在运行时dynamic加载外部插件。 在linux上可能吗? Dlopen只能与共享库和dynamic链接一起工作,因为静态二进制文件不会将任何符号导出到外部世界,那么还有其他方法吗?