共享库c ++ linux加载非虚函数

时间:2018-01-17 02:37:37

标签: c++ linux shared

我有一个共享库,它有一个具有纯虚函数的基类,还有一些实现派生类通用的函数。  基类TestAbstract.h

#ifndef TEST_ABSTRACT_H_
#define TEST_ABSTRACT_H_

class CAbstract
{
public:
        CAbstract();
        virtual ~CAbstract();

        virtual int abstractmethod() = 0;
        int test() ;
};

TestAbstract.cpp

#include <iostream>
#include "TestAbstract.h"

using namespace std;

CAbstract::CAbstract()
{
        cout << "CAbstract Base constructor" << endl;
}

CAbstract::~CAbstract()
{
        cout << "CAbstract Base destructor" << endl;
}
int CAbstract::test()
{
        cout << "CAbastract::test non-virtual function call from Base, implemented only in Base class" << endl;
        return 0;
}

派生类实现 DerivedFromAbstract.h

 #pragma once
    #include "TestAbstract.h"
    class CDerivedFromAbstract :
            public CAbstract
    {
    public:
            CDerivedFromAbstract(void);
            ~CDerivedFromAbstract(void);

            int abstractmethod();
            void derivedTest();
    };

DerivedFromAbstract.cpp

#include <iostream>
#include "DerivedFromAbstract.h"

using namespace std;

CDerivedFromAbstract::CDerivedFromAbstract(void)
{
        cout << "CDerivedFromAbstract::CDerivedFromAbstract " << endl;
}


CDerivedFromAbstract::~CDerivedFromAbstract(void)
{
        cout << "CDerivedFromAbstract::~CDerivedFromAbstract " << endl;
}

int CDerivedFromAbstract::abstractmethod()
{
        cout << "CDerivedFromAbstract::abstractmethod overriden in derived class" << endl;
        return 0;
}

void CDerivedFromAbstract :: derivedTest() {         cout&lt;&lt; “来自Derived的CDerivedFromAbstract :: derivedTest非虚函数调用”&lt;&lt; ENDL; } ObjectInterface.h

/*ObjectInterface.h
 *
 *  Created on: Jan 4, 2018
 *      Author: root
 */

#ifndef INCLUDE_OBJECTINTERFACE_H_
#define INCLUDE_OBJECTINTERFACE_H_

#include "TestAbstract.h"


// the types of the class factories

extern "C" CAbstract* create_t();
extern "C" void destroy_t(CAbstract*);


#endif /*INCLUDE_OBJECTINTERFACE_H_ */

ObjectInterface.cpp

/*
 * ObjectInterface.cpp
 *
 *  Created on: Jan 4, 2018
 *      Author: root
 */
#include "Objectinterface.h"
#include "TestAbstract.h"
#include "DerivedFromAbstract.h"

// the types of the class factories
extern "C" CAbstract* create_t()
 {
      return new CDerivedFromAbstract();

 }

 extern "C" void destroy_t(CAbstract* pObj)
 {
         if(pObj)
         {
                 delete pObj;
         }
 }

使用以下选项生成

  

g ++ -fPIC -shared -rdynamic TestAbstract.cpp DerivedFromAbstract.cpp   Objectinterface.cpp -o abstracttest.so

加载.so的主程序是

 #include <dlfcn.h>
    #include <iostream>
    #include "DerivedFromAbstract.h"

    using namespace std;

    typedef CAbstract* create_t();
    typedef void destroy_t(CAbstract*);

    int main(int argc, char **argv)
    {
      /* on Linux, use "./myclass.so" */
      void* handle = dlopen("./abstracttest.so", RTLD_LAZY);

            if(handle)
            {
            cout <<"so handle available" << endl;

            create_t* creat=(create_t*)dlsym(handle,"create_t");
            destroy_t* destroy=(destroy_t*)dlsym(handle,"destroy_t");

            if( creat)
                    {
                    cout << " calling create" << endl;
                    CAbstract* myClass = creat();
                    cout <<"calling abstractmethod" << endl;
                    myClass->abstractmethod();
                    dynamic_cast<CDerivedFromAbstract*>(myClass)->derivedTest();
                    destroy( myClass );
                    }
            }
            dlclose(handle);
    }
  

g ++ main.cpp -o stub -ldl   我收到了错误

     

/tmp/ccKvXgLa.o:在CDerivedFromAbstract的函数main': main.cpp:(.text+0xe9): undefined reference to typeinfo中   main.cpp :(。text + 0xfe):未定义的引用   `CDerivedFromAbstract :: derivedTest()'collect2:错误:ld返回1   退出状态

有没有办法可以访问加载共享库的客户端应用程序/存根中的基类非虚函数。

我可以调用虚函数,但不能调用非虚函数。

如果有人遇到过这个问题,请告诉我。我是Linux新手,如果我错过了一些简单的概念,请告诉我。

由于

1 个答案:

答案 0 :(得分:0)

不,无法访问您通过 dlopen 导入的类中的非虚函数。

由于早期绑定,你调用的每个非虚函数都应该在编译时确定它的符号,而虚函数在运行时通过 vtable/vptr 搜索它的符号。如果你想在 main.cpp 中调用它,你应该声明 derivedTest 为 virtual。

查看此链接,该链接演示了通过 dlopen 加载类的详细示例:
C++ dlopen mini HOWTO