为了代码能同时支持动态加载.dll和.so,所以使用apr。当然,直接使用windows和linux的动态加载也可以,写两个applications也能做到
For example, 动态加载libtest.dll和libtest.so
1. 新建一VS工程
2. 在工程属性中,加入apr的include路径和Lib库的所在路径
3. 在工程属性Preprocessor中,加入WINDOWSLIB
4. 在工程属性中,不需要加入libtest.lib的路径以及其他选项
5. 在LoadTest.cpp中加入如下代码就足够了:
#include <stdio.h>
#include <stdlib.h>
#include <apr_getopt.h>
#include <apr_general.h>
#include <apr_dso.h>
#include "test.h"
using namespace LoadLibrary::Test;
typedef apr_status_t (*TESTHELLO)(const char*);
class CLoadTest
{
void LoadTest()
{
#ifdef WINDOWSLIB
const char *pLibraryName= "libtest.dll";
#else
const char *pLibraryName= "libtest.so";
#endif
TESTHELLO fTestHello;
apr_pool_t * pPool = NULL;
apr_dso_handle_t *pdSOHandle = NULL;
apr_status_t result= apr_pool_create(&pPool, NULL);
// Load Library
result= apr_dso_load(&pdSOHandle, pLibraryName, pPool);
// Reference function
result= apr_dso_sym((apr_dso_handle_sym_t*)&fTestHello, pdSOHandle, "TestHello");
// Call function
result= fTestHello("everyone");
// Unload library
result= apr_dso_unload(pdSOHandle);
pdSOHandle= NULL;
apr_pool_destroy(pPool);
pPool= NULL;
}
}
6. 如果libtest.so依赖其他库libInput.so,代码中需加入对其他库里的函数的调用。只有这样,linux才能加载libInput.so
For example,
#include "Input.h"
string text=InputText();
7. 注意,一定要用(*TESTHELLO),如果直接使用TESTHELLO,会有“error LNK2019: unresolved external symbol....”
typedef apr_status_t (*TESTHELLO)(const char*);
8. 当 apr_dso_load(&pdSOHandle, pLibraryName, pPool); 返回20019时,代表有被依赖库没有被加载,可以使用ldd CLoadTest查看哪些.so被加载,从而找出没被加载的被依赖库。如果不知道依赖哪些.so,可以直接调用Linux动态加载函数dlopen等,屏幕上会输出哪个被依赖库没被加载
9. 当 apr_dso_sym((apr_dso_handle_sym_t*)&fTestHello, pdSOHandle, "TestHello");返回720127时,代表该函数没有被加载,原因可能是产品代码写错了API定义,正确的写法是:
#ifdef _cplusplus
extern "C" {
#endif
__attribute__ ((visibility("default")))
__declspec(dllexport) apr_status_t __cdecl
TestHello(const char* pcUserName);
#ifdef _cplusplus
}
#endif
可以通过使用dumpbin查看dll: dumpbin /exports libtest.dll
正确API定义的输出是:
Dump of file libtest.dll
File Type: DLL
Section contains the following exports for rnatt.dll
00000000 characteristics
5155284C time date stamp Fri Mar 29 13:36:12 2012
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 0003D13B TestHello
Summary
1000 .data
2000 .idata
11000 .rdata
4000 .reloc
1000 .rsrc
7F000 .text
3C000 .textbss
错误API定义的输出是:
Dump of file libtest.dll
File Type: DLL
Summary
1000 .data
2000 .idata
11000 .rdata
4000 .reloc
1000 .rsrc
7F000 .text
3C000 .textbss
本文介绍如何利用apr库实现跨平台动态加载.dll和.so文件。通过设置预处理器宏,根据编译环境选择对应的库文件。文章中详细阐述了加载过程,包括检查依赖库、处理未解析的外部符号错误,以及如何查看动态库的导出函数来确保API定义正确。
8696

被折叠的 条评论
为什么被折叠?



