繁体   English   中英

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

[英]shared library c++ linux loading non virtual functions

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

#ifndef TEST_ABSTRACT_H_
#define TEST_ABSTRACT_H_

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

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

测试摘要文件

#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();
    };

派生自Abstract.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 << "CDerivedFromAbstract::derivedTest 非虚函数调用来自 Derived" << endl; 对象接口.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_ */

对象接口.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: 在函数main': main.cpp:(.text+0xe9): undefined reference to CDerivedFromAbstract 的 typeinfo 的main': main.cpp:(.text+0xe9): undefined reference to main.cpp:(.text+0xfe): 对`CDerivedFromAbstract::derivedTest( )' collect2: 错误: ld 返回 1 个退出状态

有什么方法可以访问正在加载共享库的客户端应用程序/存根中的基类非虚拟函数。

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

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

谢谢

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM