库不能正确导出功能
Library not exporting function properly
我有一个Windows和Linux的共享库(.dll和.so)。除了用于平台之间差异的一些定义外,代码完全相同。Windows-DLL工作正常,所有的符号都被导出,可以被调用者使用。
但是在Linux下有一个问题,当尝试调用其中一个函数时,调用应用程序以"symbol not found"消息终止。令人惊讶的是,当我查看。so文件(使用Midnight Commander)时,我可以看到相关的符号在那里,所以在我看来,它没有理由失败!
这是一个标准库定义的示例。
标题:
#ifdef ENV_LINUX
#ifdef MY_EXPORTS
#define MY_API __attribute ((visibility ("default")))
#else
#define MY_API
#endif
#else
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
#endif
#ifdef __cplusplus
extern "C"
{
#endif
MY_API unsigned char MY_set_connection(const char *address);
#ifdef __cplusplus
};
#endif // __cplusplus
和实现:
MY_API unsigned char MY_set_connection(const char *address)
{
// some code here
}
所以头文件和c文件中的函数定义是相同的,库是用
构建的CCOMPILER=libtool --mode=compile g++ -Wall -Wno-unused -fPIC -shared -fvisibility=hidden $(DBGFLAGS) -DMY_EXPORTS -D_REENTRANT -DENV_LINUX -I. -I.. $(CFLAGS) $(LFLAGS)
LINK=libtool --mode=link g++ -rpath /usr/lib
所以在我看来,应该没有理由在运行时找不到符号。知道原因是什么吗?
你的链接有问题。在编译时而不是运行时找到了符号?您是否使用dl_open
来运行时链接库?
我把这个简单的例子放在一起调试。
#include <iostream>
#ifdef ENV_LINUX
#ifdef MY_EXPORTS
#define MY_API __attribute ((visibility ("default")))
#else
#define MY_API
#endif
#else
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
#endif
#ifdef __cplusplus
extern "C"
{
#endif
MY_API unsigned char MY_set_connection(const char *address);
#ifdef __cplusplus
};
#endif // __cplusplus
unsigned char MY_set_connection(const char* address)
{
std::cout << "found it" << std::endl;
return 0;
}
然后编译并查看符号
/tmp$ g++ -fPIC -g -std=c++11 -shared -fvisibility=hidden -DMY_EXPORTS -D_REENTRANT -DENV_LINUX -o libtest_library.so lib.cpp
/tmp$ nm -D libtest_library.so | grep MY_set_connection
00000000000007c5 T MY_set_connection
现在是一个简单的主
#ifdef __cplusplus
extern "C"
{
#endif
unsigned char MY_set_connection(const char *address);
#ifdef __cplusplus
};
#endif // __cplusplus
int main(int argc, char* argv[])
{
unsigned char rc = MY_set_connection("test");
return 0;
}
编译并检查符号依赖
/tmp$ g++ -g -std=c++11 junk.cpp -DENV_LINUX -L . -l test_library
/tmp$ g++ -g junk.cpp -DENV_LINUX -L . -l test_library
/tmp$ nm a.out | grep MY_
U MY_set_connection
MY_set_connection是'U',在main中是未定义的。符号是"T",这是文本部分和外部,也是预期的。运行程序按预期工作。看看你的符号依赖于nm,也许符号状态是错误的。
另一种可能是外部C签名在库或主程序中是错误的。确保符号在nm输出
中没有被打乱。查看ldd输出,以确保在运行时链接到正确的库。运行时链接到错误版本的共享库将会给出未定义的符号。
ldd ./a.out
libtest_library.so => /tmp/libtest_library.so (0x00002b5df4ca7000)
相关文章:
- 为什么我不能拥有某些私有会员功能?
- 为什么这个base64解码/编码功能不能正常工作?
- C++ - 多态性:不能使用功能
- 为什么在传递lambda而不是功能指针时不能推断模板参数
- MPI_Op_create:候选功能不可行.自定义结构指针不能解释为空指针
- 制作uint128库却不能,找出什么功能搞砸了
- opencv2 可以使用 cmake 构建,但不能使用 CLion "build" 功能?
- 我不能在函数中使用新功能C++构建
- 不能在QtCreator中使用使用g++ 7.2的c ++ 17功能
- 为什么不能将std :: stol转换为std ::功能对象
- 为什么这两个功能不能超载
- 为什么不能从指针施放到模板功能中的指针
- 我正在使用Xcode进行c ++编程和学习。为什么我不能在一个项目中放置许多具有 MAIN 功能的单独源文件?
- 我不能在不使用指针的情况下返回 2d 数组!我正在制作一个井字游戏类型游戏,这是我的向上移动功能
- 虚拟功能不能是朋友
- "官方"CUDA 减少功能不能接受某些数字?
- 问题.所有功能都可以在发布文件夹中工作,但不能在程序文件中工作
- std::ref 和交换功能似乎不能很好地协同工作
- 在NVI成语下,为什么虚拟功能不能公开?
- 洗牌功能不能正常工作