2

私は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
4

1 に答える 1