我有一个可执行文件和一个动态库(.so).该库成功导出一些符号和可执行调用.但我希望库调用可执行文件的功能.我试过在可执行文件中做以下操作:
//test
extern "C" void print(const char * str) {
std::cout << str << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这在图书馆:
extern "C" void print(const char *);
Run Code Online (Sandbox Code Playgroud)
但是当我调用dlopen可执行文件(加载库)时,它返回错误undefined symbol: print.我该怎么办呢?
SO有大量 关于如何执行库或动态加载可执行文件的问题。据我所知,所有答案都归结为:将可执行文件编译为位置无关代码并使用. 这非常有效,并且在 macOS 上仍然有效,直到glibc 最近发生更改,明确禁用了PIE。例如,此更改现在出现在 ArchLinux 上当前版本的 glibc (2.30) 中,并且尝试位置无关的可执行文件会出现错误:“无法动态加载位置无关的可执行文件”。dlopendlopendlopen
很难猜测是什么促使了如此彻底的改变,破坏了如此多的代码和有用的用例。(Patchwork 和 Bugzilla 的解释对我来说没有多大意义。)但是现在有一个问题:如果你想创建一个同时也是动态库的可执行文件该怎么办,反之亦然?
其中一条评论链接了一个解决方案。在这里为后代复制它:
#include <stdio.h>
#include <unistd.h>
const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux-x86-64.so.2";
extern "C" {
void lib_entry(void)
{
printf("Entry point of the service library\n");
_exit(0);
}
}
Run Code Online (Sandbox Code Playgroud)
编译生成g++ -shared test-no-pie.cpp -o test-no-pie -Wl,-e,lib_entry一个也可以在 Linux 上执行的共享对象(动态库)。
我有两个问题:
arc,argv?这是一个理论问题.我知道也许最好的做法是使用共享库.但我遇到了这个问题,似乎无法在任何地方找到答案.
如何构建代码并用ELF格式编译一个C/C++程序,以便可以加载dlopen()?
例如,如果一个可执行文件包含某个函数的实现,int test()并且我想从我的程序中调用此函数(并且最好得到函数的结果),如果可能的话,我该怎么做呢?
在伪代码中,我可以将其描述如下:
ELF可执行文件来源:
void main() {
int i = test();
printf("Returned: %d", i);//Prints "Returned: 5"
}
int test() {
return 5;
}
Run Code Online (Sandbox Code Playgroud)
外部计划:
// ... Somehow load executable from above
void main() {
int i = test();
printf("Returned: %d", i);//Must print "Returned: 5"
}
Run Code Online (Sandbox Code Playgroud) 我写了一个程序来自我解决
void hello()
{
printf("hello world\n");
}
int main(int argc, char **argv)
{
char *buf="hello";
void *hndl = dlopen(argv[0], RTLD_LAZY);
void (*fptr)(void) = dlsym(hndl, buf);
if (fptr != NULL)
fptr();
dlclose(hndl);
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了"segemention fault"错误我用.so库测试了这个程序并且它可以工作但不能让它自己工作
如果我有一个指向函数的指针,并将其交给另一个(Unrelated/Child)可执行文件,如何在不进行段错误的情况下调用该函数?
目前我可以创建一个函数并为其分配这个内存地址:
Dim As Function (ByRef As String) As Integer MyFunction
' get pointer...
MyFunction = FunctionPointer
Run Code Online (Sandbox Code Playgroud)
但后来调用MyFunction我得到一个段错误(显然是因为我调用的函数是在另一个可执行文件的地址空间,我不允许访问)
我该如何解决这个/解决它?