我需要从我自己的应用程序中调用导出的符号 - 因此我需要知道在“自己”上调用dlopen
/ LoadLibrary
是否安全。
一个例子是:
LoadLibrary("test.exe");
在名为test.exe
的程序中。
我测试过它似乎有用,但我不太确定它是否真的受到支持。
答案 0 :(得分:5)
来自MSDN文档here ...
系统维护所有已加载模块的每进程引用计数。调用 LoadLibrary 会增加引用计数。调用 FreeLibrary 或 FreeLibraryAndExitThread 函数会减少引用计数。系统在其引用计数达到零或进程终止时卸载模块(无论引用计数如何)。
它会起作用,只需记住如上所述,通过致电FreeLibrary来清理自己。
非常想要的是GetModuleHandle。
检索指定模块的模块句柄。该模块必须已由调用进程加载。
事实上,你所要做的甚至是一个特例。
lpModuleName [in,optional]
... 的
如果此参数为NULL, GetModuleHandle 将返回用于创建调用进程(.exe文件)的文件的句柄。
所以,试试这个......
#include <stdio.h>
#include <windows.h>
__declspec(dllexport) void print(void) {
puts("OK");
}
main() {
HMODULE mod = GetModuleHandle(0);
FARPROC proc = GetProcAddress(mod, "print");
proc();
return 0;
}
......似乎有效:
C:\dev\scrap>gcc -oprint print.c
C:\dev\scrap>print
OK
对于dlopen,它看起来非常相似。
如果 filename 是NULL指针,则返回的句柄用于主程序。当给予 dlsym ()时,此句柄会导致在主程序中搜索符号,然后搜索程序启动时加载的所有共享库,然后搜索由 dlopen加载的所有共享库(),标记为 RTLD_GLOBAL 。
答案 1 :(得分:2)
你可以用dlopen()
轻松地做到这一点 - 有一个伪句柄作为GNU扩展,RTLD_DEFAULT
就像一个自己的句柄,所以你可以简单地跳过dlopen()
调用并写:
dlsym(RTLD_DEFAULT, "entry_func");
例如:
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <assert.h>
void print(void) {
puts("OK");
}
int main() {
void (*proc)(void) = dlsym(RTLD_DEFAULT, "print");
assert(proc);
proc();
return 0;
}
请注意,您需要使用-rdynamic
进行编译才能实现此目的。
根据最新的Solaris计算机上的联机帮助页RTLD_DEFAULT
也可以使用。
答案 2 :(得分:1)
Windows上的快速测试:
#include <windows.h>
#include <stdio.h>
__declspec(dllexport) FARPROC Test() {
printf("It worked");
}
int main(int argc, char **argv) {
HMODULE m = LoadLibrary(argv[0]);
FARPROC test = GetProcAddress(m, "Test");
test();
return 0;
}
产生了以下输出:
It worked
我认为理论上并不保证它可能不会破坏其他版本的Windows,但我认为这是值得怀疑的。