Как создать общий объект с высокой ремонтопригодностью? - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь создать общий объект для своего проекта C ++ с целью: каждый раз, когда я хочу создать новый класс, я перекомпилирую только общий объект.

ниже приведен код теста:

test.h:

#if !defined(_TEST_)
#define _TEST_

#include <string>
#include <memory>

class Test {
private:

public:
    Test() {

    }
    ~Test() {

    }

    virtual void show(const std::string &) = 0;
};

#ifdef __cplusplus
extern "C" {
#endif

// std::shared_ptr<Test> getObject();

#ifdef __cplusplus
}
#endif

#endif // _TEST_  

getObject.cpp: класс TestSo является производным от Test.

#include <memory>
#include "testso.h"

std::shared_ptr<Test> getObject()
{
    return std::make_shared<TestSo>();
}  

и main.cpp:

#include "test.h"

#include <dlfcn.h>
#include <string>

#include <memory>

std::shared_ptr<Test> (*getTestSo)();

int main(int argc, char const *argv[])
{
    //...
    void *handle = dlopen("/usr/lib/libfunc.so", RTLD_NOW);
    if(handle == NULL)
        return 1;

    getTestSo = (std::shared_ptr<Test> (*)())dlsym(handle, "getObject");

    const char *dlmsg = dlerror();
    if(dlmsg != NULL) {
        printf("dlsym: %s\n", dlmsg);
        dlclose(handle);
        return 1;
    }

    std::shared_ptr<Test> classSo = getTestSo();

    classSo->show("Hi");

    dlclose(handle);
    //...
    return 0;
}  

Я компилирую код со следующей командной строкой:
arm-none-linux-gnueabi-g++ -std=c++11 -c -fPIC getObject.cpp
arm-none-linux-gnueabi-g++ -shared getObject.o -o libtest.so
arm-none-linux-gnueabi-g++ -std=c++11 -L./ main.cpp -o test -ldl -ltest

компилятор не выдает мне ни предупреждения, ни ошибки.это говорит, что undefined symbol: getObject, когда я запускаю программу.

наконец я обнаружил, что я должен объявить getObject в области действия extern "C" в пределах test.h.

dlsym получить адрес getObject из libtest.so, и программа перейдет на этот адрес.почему я должен объявить getObject?это против моей цели.Или, если я иду по неправильному пути, как мне поступить?если нет, как я могу это исправить?

Редактировать:

arm-none-linux-gnueabi-nm -D libfunc.so 
         U __aeabi_atexit
         U __aeabi_unwind_cpp_pr0
         U __aeabi_unwind_cpp_pr1
0000f34c B __bss_end__
0000f34c B _bss_end__
0000f344 B __bss_start
0000f344 B __bss_start__
         U __cxa_begin_catch
         U __cxa_end_catch
         U __cxa_end_cleanup
         w __cxa_finalize
         U __cxa_pure_virtual
         U __cxa_rethrow
0000f344 D _edata
0000f34c B _end
0000f34c B __end__
00006664 T _fini
         w __gmon_start__
         U __gxx_personality_v0
00003e18 T _init
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         w _Jv_RegisterClasses
         w __pthread_key_create
0000448c T _Z9getObjectv
         U _ZdlPv
000045a4 W _ZdlPvS_
00004630 W _ZN4TestC1Ev
00004630 W _ZN4TestC2Ev
00004678 W _ZN4TestD1Ev
00004678 W _ZN4TestD2Ev
00004760 W _ZN6TestDl4showERKSs
000046c0 W _ZN6TestDlC1Ev
000046c0 W _ZN6TestDlC2Ev
00004710 W _ZN6TestDlD1Ev
00004710 W _ZN6TestDlD2Ev
0000569c W _ZN9__gnu_cxx13new_allocatorI6TestDlE7destroyIS1_EEvPT_
00005424 W _ZN9__gnu_cxx13new_allocatorI6TestDlE9constructIS1_IEEEvPT_DpOT0_
00005424 W _ZN9__gnu_cxx13new_allocatorI6TestDlE9constructIS1_JEEEvPT_DpOT0_
000052d8 W _ZN9__gnu_cxx13new_allocatorI6TestDlEC1ERKS2_
00004af8 W _ZN9__gnu_cxx13new_allocatorI6TestDlEC1Ev
000052d8 W _ZN9__gnu_cxx13new_allocatorI6TestDlEC2ERKS2_
00004af8 W _ZN9__gnu_cxx13new_allocatorI6TestDlEC2Ev
00004b1c W _ZN9__gnu_cxx13new_allocatorI6TestDlED1Ev
00004b1c W _ZN9__gnu_cxx13new_allocatorI6TestDlED2Ev
000050bc W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEE10deallocateEPS5_j
000056c0 W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEE7destroyIS5_EEvPT_
00005018 W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEE8allocateEjPKv
0000510c W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEE9constructIS5_IKS3_EEEvPT_DpOT0_
0000510c W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEE9constructIS5_JKS3_EEEvPT_DpOT0_
00004fd0 W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEEC1Ev
00004fd0 W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEEC2Ev
00004ff4 W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEED1Ev
00004ff4 W _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEED2Ev
000045c4 W _ZN9__gnu_cxx7__mutexC1Ev
000045c4 W _ZN9__gnu_cxx7__mutexC2Ev
000050e4 W _ZNK9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI6TestDlSaIS2_ELNS_12_Lock_policyE1EEE8max_sizeEv
00004e5c W _ZNKSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EE14_M_get_deleterERKSt9type_info
         U _ZNKSt9type_infoeqERKS_
000051a0 W _ZNSaI6TestDlEC1ERKS0_
00004934 W _ZNSaI6TestDlEC1Ev
000051a0 W _ZNSaI6TestDlEC2ERKS0_
00004934 W _ZNSaI6TestDlEC2Ev
0000495c W _ZNSaI6TestDlED1Ev
0000495c W _ZNSaI6TestDlED2Ev
00004edc W _ZNSaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEEC1IS0_EERKSaIT_E
00004edc W _ZNSaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEEC2IS0_EERKSaIT_E
00004f08 W _ZNSaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEED1Ev
00004f08 W _ZNSaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEED2Ev
         U _ZNSolsEPFRSoS_E
000048f4 W _ZNSt10shared_ptrI4TestEC1I6TestDlvEEOS_IT_E
000048f4 W _ZNSt10shared_ptrI4TestEC2I6TestDlvEEOS_IT_E
00004b40 W _ZNSt10shared_ptrI6TestDlEC1ISaIS0_EIEEESt19_Sp_make_shared_tagRKT_DpOT0_
00004b40 W _ZNSt10shared_ptrI6TestDlEC1ISaIS0_EJEEESt19_Sp_make_shared_tagRKT_DpOT0_
00004b40 W _ZNSt10shared_ptrI6TestDlEC2ISaIS0_EIEEESt19_Sp_make_shared_tagRKT_DpOT0_
00004b40 W _ZNSt10shared_ptrI6TestDlEC2ISaIS0_EJEEESt19_Sp_make_shared_tagRKT_DpOT0_
00004808 W _ZNSt10shared_ptrI6TestDlED1Ev
00004808 W _ZNSt10shared_ptrI6TestDlED2Ev
00005300 W _ZNSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE1EEC1Ev
00005300 W _ZNSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE1EEC2Ev
00004a8c W _ZNSt12__shared_ptrI4TestLN9__gnu_cxx12_Lock_policyE1EEC1I6TestDlvEEOS_IT_LS2_1EE
00004a8c W _ZNSt12__shared_ptrI4TestLN9__gnu_cxx12_Lock_policyE1EEC2I6TestDlvEEOS_IT_LS2_1EE
00004c00 W _ZNSt12__shared_ptrI6TestDlLN9__gnu_cxx12_Lock_policyE1EEC1ISaIS0_EIEEESt19_Sp_make_shared_tagRKT_DpOT0_
00004c00 W _ZNSt12__shared_ptrI6TestDlLN9__gnu_cxx12_Lock_policyE1EEC1ISaIS0_EJEEESt19_Sp_make_shared_tagRKT_DpOT0_
00004c00 W _ZNSt12__shared_ptrI6TestDlLN9__gnu_cxx12_Lock_policyE1EEC2ISaIS0_EIEEESt19_Sp_make_shared_tagRKT_DpOT0_
00004c00 W _ZNSt12__shared_ptrI6TestDlLN9__gnu_cxx12_Lock_policyE1EEC2ISaIS0_EJEEESt19_Sp_make_shared_tagRKT_DpOT0_
000047d8 W _ZNSt12__shared_ptrI6TestDlLN9__gnu_cxx12_Lock_policyE1EED1Ev
000047d8 W _ZNSt12__shared_ptrI6TestDlLN9__gnu_cxx12_Lock_policyE1EED2Ev
00004bb8 W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EE7_M_swapERS2_
00004a5c W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EEC1Ev
00004d84 W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EEC1I6TestDlSaIS4_EIEEESt19_Sp_make_shared_tagPT_RKT0_DpOT1_
00004d84 W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EEC1I6TestDlSaIS4_EJEEESt19_Sp_make_shared_tagPT_RKT0_DpOT1_
00004a5c W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EEC2Ev
00004d84 W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EEC2I6TestDlSaIS4_EIEEESt19_Sp_make_shared_tagPT_RKT0_DpOT1_
00004d84 W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EEC2I6TestDlSaIS4_EJEEESt19_Sp_make_shared_tagPT_RKT0_DpOT1_
00004890 W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EED1Ev
00004890 W _ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EED2Ev
0000564c W _ZNSt16allocator_traitsISaI6TestDlEE10_S_destroyIS0_EENSt9enable_ifIXsrNS2_16__destroy_helperIT_EE5valueEvE4typeERS1_PS6_
000053fc W _ZNSt16allocator_traitsISaI6TestDlEE12_S_constructIS0_IEEENSt9enable_ifIXsrNS2_18__construct_helperIT_IDpT0_EEE5valueEvE4typeERS1_PS6_DpOS7_
000053fc W _ZNSt16allocator_traitsISaI6TestDlEE12_S_constructIS0_JEEENSt9enable_ifIXsrNS2_18__construct_helperIT_JDpT0_EEE5valueEvE4typeERS1_PS6_DpOS7_
000055fc W _ZNSt16allocator_traitsISaI6TestDlEE7destroyIS0_EEvRS1_PT_
000053d4 W _ZNSt16allocator_traitsISaI6TestDlEE9constructIS0_IEEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS1_PT_DpOS4_
000053d4 W _ZNSt16allocator_traitsISaI6TestDlEE9constructIS0_JEEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS1_PT_DpOS4_
00004fa0 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE10deallocateERS6_PS5_j
00005674 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE10_S_destroyIS5_EENSt9enable_ifIXsrNS7_16__destroy_helperIT_EE5valueEvE4typeERS6_PSB_
00005080 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE12_S_constructIS5_IKS2_EEENSt9enable_ifIXsrNS7_18__construct_helperIT_IDpT0_EEE5valueEvE4typeERS6_PSC_DpOSD_
00005080 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE12_S_constructIS5_JKS2_EEENSt9enable_ifIXsrNS7_18__construct_helperIT_JDpT0_EEE5valueEvE4typeERS6_PSC_DpOSD_
00005624 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE7destroyIS5_EEvRS6_PT_
00004f30 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE8allocateERS6_j
00004f64 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE9constructIS5_IKS2_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS6_PT_DpOSA_
00004f64 W _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI6TestDlSaIS1_ELN9__gnu_cxx12_Lock_policyE1EEEE9constructIS5_JKS2_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS6_PT_DpOSA_
00004b7c W _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE10_M_destroyEv
000049b4 W _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE10_M_releaseEv
0000532c W _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EEC1Ev
0000532c W _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EEC2Ev
00004d0c W _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EED0Ev
00004cb4 W _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EED1Ev
00004cb4 W _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EED2Ev
0000553c W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE10_M_destroyEv
00005508 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE10_M_disposeEv
0000559c W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE14_M_get_deleterERKSt9type_info
00005398 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE5_ImplC1ES1_
00005398 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE5_ImplC2ES1_
000051d0 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE5_ImplD1Ev
000051d0 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE5_ImplD2Ev
000051f8 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEC1IIEEES1_DpOT_
000051f8 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEC1IJEEES1_DpOT_
000051f8 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEC2IIEEES1_DpOT_
000051f8 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EEC2IJEEES1_DpOT_
000054d8 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EED0Ev
00005464 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EED1Ev
00005464 W _ZNSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EED2Ev
         U _ZNSt8ios_base4InitC1Ev
         U _ZNSt8ios_base4InitD1Ev
         U _Znwj
0000457c W _ZnwjPv
00004834 W _ZSt11make_sharedI6TestDlIEESt10shared_ptrIT_EDpOT0_
00004834 W _ZSt11make_sharedI6TestDlJEESt10shared_ptrIT_EDpOT0_
00004984 W _ZSt15allocate_sharedI6TestDlSaIS0_EIEESt10shared_ptrIT_ERKT0_DpOT1_
00004984 W _ZSt15allocate_sharedI6TestDlSaIS0_EJEESt10shared_ptrIT_ERKT0_DpOT1_
         U _ZSt17__throw_bad_allocv
00004ec0 W _ZSt32__enable_shared_from_this_helperILN9__gnu_cxx12_Lock_policyE1EEvRKSt14__shared_countIXT_EEz
         U _ZSt4cout
         U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00004d3c W _ZSt4moveIRKSaI6TestDlEEONSt16remove_referenceIT_E4typeEOS5_
000048d0 W _ZSt4moveIRSt10shared_ptrI6TestDlEEONSt16remove_referenceIT_E4typeEOS5_
00004d60 W _ZSt7forwardIKSaI6TestDlEEOT_RNSt16remove_referenceIS3_E4typeE
         U _ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E
         U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
0000f098 V _ZTI4Test
0000f08c V _ZTI6TestDl
0000f0c4 V _ZTIN9__gnu_cxx7__mutexE
0000f0b8 V _ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE1EE
0000f0a0 V _ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE
0000f084 V _ZTISt19_Sp_make_shared_tag
0000f078 V _ZTISt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE
000066f8 V _ZTS4Test
000066f0 V _ZTS6TestDl
00006764 V _ZTSN9__gnu_cxx7__mutexE
00006734 V _ZTSSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE1EE
00006700 V _ZTSSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE
000066d8 V _ZTSSt19_Sp_make_shared_tag
0000668c V _ZTSSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE
0000f048 V _ZTV4Test
0000f038 V _ZTV6TestDl
         U _ZTVN10__cxxabiv117__class_type_infoE
         U _ZTVN10__cxxabiv120__si_class_type_infoE
         U _ZTVN10__cxxabiv121__vmi_class_type_infoE
0000f058 V _ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE
0000f018 V _ZTVSt23_Sp_counted_ptr_inplaceI6TestDlSaIS0_ELN9__gnu_cxx12_Lock_policyE1EE  

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Ниже приведен рабочий пример для вас.

Нет необходимости в extern "C" связывании, поскольку вы можете точно найти и использовать искаженное имя C ++.

Кроме того, фабричные функции должны возвращать std::unique_ptr, чтобы передать пользователю, чтотеперь они владеют объектом.Если только фабрика не хранит ссылку на объект, в этом случае std::shared_ptr будет хорошим выбором.

Заголовок общей библиотеки:

// shared.h
#pragma once

#include <memory>
#include <string>
#include <iosfwd>

namespace shared {

struct Test {
    virtual ~Test() = 0;
    virtual void print(std::ostream&) const = 0;

    // Factory function.
    static std::unique_ptr<Test> create(std::string const& type);
};

inline std::ostream& operator<<(std::ostream& s, Test const& t) {
    t.print(s);
    return s;
}

} // namespace shared

Источник общей библиотеки:

// shared.cc
#include "shared.h"
#include <iostream>

namespace {

struct A : shared::Test {
    void print(std::ostream& s) const override {
        s << __PRETTY_FUNCTION__;
    }
};

} // namespace

shared::Test::~Test() = default;

std::unique_ptr<shared::Test> shared::Test::create(std::string const& type) {
    std::unique_ptr<Test> result;
    if(type == "A")
        result.reset(new A);
    return result;
}

Создайте общую библиотеку и найдите искаженное имя Test::create:

$ g++ -c -fPIC -W{all,extra,error} -std=c++11 shared.cc
$ g++ -o libshared.so -shared shared.o
$ nm --demangle --defined-only --dynamic libshared.so | grep Test::create
0000000000001894 T shared::Test::create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
$ nm --defined-only --dynamic libshared.so | grep 0000000000001894
0000000000001894 T _ZN6shared4Test6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

Источник пользователя:

// test.cc
#include "shared.h"
#include <iostream>
#include <dlfcn.h>

struct DlClose { void operator()(void* handle) const { ::dlclose(handle); } };
using dl_ptr = std::unique_ptr<void, DlClose>;

int main() {
    dl_ptr handle(::dlopen("./libshared.so", RTLD_NOW));
    if(!handle)
        std::abort();

    using FactoryFn = std::unique_ptr<shared::Test>(std::string const&);
    FactoryFn* shared_create = reinterpret_cast<FactoryFn*>(::dlsym(handle.get(), "_ZN6shared4Test6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"));
    if(!shared_create)
        std::abort();

    auto a = shared_create("A");
    std::cout << *a << '\n';
}

Создайте и запустите код пользователя:

$ g++ -W{all,extra,error} -std=c++11 -o test -ldl test.cc
$ ./test
virtual void {anonymous}::A::print(std::ostream&) const
0 голосов
/ 21 ноября 2018

Ваш подход не работает, потому что C ++ искажает имена во время компиляции, возможно, больше по этой теме можно найти в сети или, например, в этой теме .Когда вы компилируете функцию с именем std::shared_ptr<Test> getObject(), она заканчивается как символ с именем _Z9getObjectv, поэтому вам нужно открывать этот символ dlsym(handle, "_Z9getObjectv");

каждый раз, когда я хочу принести новый класс,Я перекомпилирую только общий объект.

Я не понимаю, почему вы не хотите просто ссылаться на вашу программу.dlsym был создан, чтобы позволить связанным с линкером программам обрабатывать загрузку, функциональность в вашей программе, похоже, не нужна.В случае вашей программы просто добавьте предварительное объявление функции (без какого-либо внешнего C, потому что имя искажено C ++):

std::shared_ptr<Test> getObject();

в ваш файл test.h, а затем скомпилируйте с:

-ltest

как вы сейчас (!) Будете ссылаться на разделяемую библиотеку.Это именно та причина, по которой разделяемые библиотеки существуют в первую очередь - поэтому вы можете изменить базовый код без изменения клиентского кода.Также в случае ссылки компоновщик выдаст ошибку разрешения символа, если символ не найден, поэтому у вас есть еще один уровень защиты, и вам не нужно беспокоиться о искаженных именах.Просто измените ваш main.cpp на:

#include "test.h"

#include <dlfcn.h>
#include <string>

#include <memory>

int main(int argc, char const *argv[])
{
    std::shared_ptr<Test> getObject();
    std::shared_ptr<Test> (*getTestSo)() = getObject;

    std::shared_ptr<Test> classSo = getTestSo();

    return 0;
}  

, и он должен работать (при правильном LD_LIBRARY_PATH) ...

...