同一应用程序上的dlopen/LoadLibrary
dlopen/LoadLibrary on same application
我需要从自己的应用程序中调用导出的符号,因此我需要知道在"自己"上调用dlopen
/LoadLibrary
是否安全。
例如:
LoadLibrary("test.exe");
在一个名为CCD_ 3的程序中。
我测试了它,它似乎有效,但我不太确定它是否真的是受支持的行为。
从MSDN文档中。。。
系统在所有加载的模块上维护每个过程的参考计数。调用LoadLibrary会增加引用计数。调用FreeLibrary或FreeLibraryAndExitThread函数会减少引用计数。当模块的引用计数达到零时或进程终止时(无论引用计数如何),系统都会卸载模块。
它会起作用的,只需记得打电话给FreeLibrary进行清理,如上所述。
您可能真正想要的是GetModuleHandle。
检索指定模块的模块句柄。模块必须已由调用进程加载。
事实上,你试图做的事情甚至是一个特殊的情况。
lpModuleName[in,可选]
如果此参数为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:devscrap>gcc -oprint print.c
C:devscrap>print
OK
对于dlopen来说,它看起来非常相似。
如果filename是NULL指针,则返回的句柄用于主程序。当指定给dlsym()时,此句柄将导致在主程序中搜索一个符号,然后是在程序启动时加载的所有共享库,然后是dlopen加载的所有具有RTLD_GLOBAL标志的共享库。
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上崩溃,但我认为这相当可疑。
你可以用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
也在那里可用。
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- Windows 链接器是否使用 LoadLibrary 解析 DLL 中未定义的符号?
- 如何将 std::filesystem::p ath 转换为 LPCSTR,以便在 LoadLibrary() 变体之一
- 对 DLOPEN 的未定义引用
- 为什么 LoadLibrary 失败,而 LoadLibraryA 成功加载 DLL?
- Linux 可执行文件通过 dlopen 在emplace_back崩溃打开共享库
- 如何链接 DLL 以供 LoadLibrary() 使用(在 Windows 上的 C++ 中)并从调用 exe 导入变
- 使用 dlopen 加载派生的多态类
- 从DLL导出函数,LoadLibrary()需要用TEXT转换的字符串才能编译而不会出错
- 'dlopen''ing 包含符号的 .so 会导致未定义的符号
- 使用 dlopen 在 Mac 上加载 libjvm.dylib 时发出信号 SIGSEGV
- LoadLibrary:在发布模式下崩溃
- 在加载了dlopen的库中使用std::thread会导致sigsev
- 卸载共享对象(.so 文件)在 C++ 中用 dlopen() 打开
- RTLD_NOW和 dlopen 未在此范围内声明 qt 创建者 vulkan dlopen
- Java System.loadLibrary 不会在 /usr/lib/x86_64-linux-gnu/ 文件夹中查
- dlopen(RTLD_NOLOAD) 在 dlclose() 仍然返回 not null
- 使用 dlopen/dlsym 打开C++共享库 - dlsym 返回 NULL
- C 中的简单现代跨平台Dlopen/LoadLibrary包装器
- 同一应用程序上的dlopen/LoadLibrary