我正在玩 dylib 多次加载并尝试了解是什么使符号不同。
这是我的步骤:
使用以下入口点构建 lib_a.dylib:
FactoryA : IFActory () {} extern "C" IFactory* GetFactory () { return new FactoryA(); }
- 将 lib_a.dylib 复制到 lib_b.dylib
从 lib_a.dylib 和 lib_b.dylib 加载 GetFactory
void * module=dlopen(fileName,RTLD_LAZY); void * proc = (void *)dlsym(module, "GetFactory");
在加载第二个dylib(lib_b.dylib)时,GetFactory 被认为已经被lib_a.dylib 定义了。
实际上,nm 输出具有相同的结果。
但我认为编译标签 -two_level_namespace 保证 2 个 dylib 位于一种不同的命名空间中,我错了吗?
我可以改变什么来加载我的两个 dylib?
下面是我的测试。
myclass.h:
#include <stdio.h>
class IFactory {
public:
virtual int GetCount() = 0;
};
extern "C"
{
extern IFactory* GetFactory ();
}
我的类.cpp
#include <stdio.h>
#include "myclass.h"
class MyFactory : public IFactory {
public:
virtual int GetCount() { mCount++; return mCount; }
static int mCount;
};
int MyFactory::mCount = 0;
IFactory* GetFactory () {
return new MyFactory;
}
我的测试.cpp
#include <stdio.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
#include "myclass.h"
typedef IFactory* (*factoryPtr)();
int main()
{
void* handleA = dlopen("libmylib.dylib", RTLD_LAZY);
factoryPtr functionA = (IFactory*(*)())dlsym(handleA, "GetFactory");
IFactory* factoryA = (*functionA)();
fprintf(stderr, "Handle A: %p\tFunction A: %p\t Count: %d\n", handleA, functionA, factoryA->GetCount());
// Reload same library
void* handleB = dlopen("libmylib.dylib", RTLD_LAZY);
factoryPtr functionB = (IFactory*(*)())dlsym(handleB, "GetFactory");
IFactory* factoryB = (*functionB)();
fprintf(stderr, "Handle B: %p\tFunction B: %p\t Count: %d\n", handleB, functionB, factoryB->GetCount());
// Load copy of first library (just rename)
void* handleC = dlopen("libmylib_copy.dylib", RTLD_LAZY);
factoryPtr functionC = (IFactory*(*)())dlsym(handleC, "GetFactory");
IFactory* factoryC = (*functionC)();
fprintf(stderr, "Handle C: %p\tFunction C: %p\t Count: %d\n", handleC, functionC, factoryC->GetCount());
return 0;
}
命令 :
clang++ -dynamiclib myclass.cpp -o libmylib.dylib
cp libmylib.dylib libmylib_copy.dylib
clang++ mytest.cpp -o mytest
./mytest
输出 :
Handle A: 0x7fe5dac039b0 Function A: 0x106d49d30 Count: 1
Handle B: 0x7fe5dac039b0 Function B: 0x106d49d30 Count: 2
Handle C: 0x7fe5dac03e00 Function C: 0x106d7cd30 Count: 3
为什么我们最后有 count = 3 ?
属性 -fvisibility=hidden -fvisibility-inlines-hidden 允许这样做。
修改 myclass.h :
#include <stdio.h>
#define EXPORT_FACTORY __attribute__ ((visibility ("default")))
class IFactory {
public:
virtual int GetCount() = 0;
};
extern "C"
{
extern EXPORT_FACTORY IFactory* GetFactory ();
}
建造 :
clang++ -dynamiclib myclass.cpp -o libmylib.dylib -fvisibility=hidden -fvisibility-inlines-hidden
cp libmylib.dylib libmylib_copy.dylib
clang++ mytest.cpp -o mytest
./mytest
输出 :
Handle A: 0x7fe078c039b0 Function A: 0x1076e1c00 Count: 1
Handle B: 0x7fe078c039b0 Function B: 0x1076e1c00 Count: 2
Handle C: 0x7fe078c03e20 Function C: 0x107714c00 Count: 1