私は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");
2 番目の dylib (lib_b.dylib) をロードするとき、GetFactory は lib_a.dylib によって既に定義されていると見なされます。
事実上、nm出力は同じ結果になります。
しかし、コンパイルタグ -two_level_namespace は、2つのdylibが一種の異なる名前空間にあることを保証していると思いましたが、間違っていますか?
2 つの dylib をロードするために何を変更できますか?
以下は私のテストです。
myclass.h :
#include <stdio.h>
class IFactory {
public:
virtual int GetCount() = 0;
};
extern "C"
{
extern IFactory* GetFactory ();
}
myclass.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;
}
mytest.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