共享库 C++ Linux 加载非虚拟函数



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

#ifndef TEST_ABSTRACT_H_
#define TEST_ABSTRACT_H_
class CAbstract
{
public:
CAbstract();
virtual ~CAbstract();
virtual int abstractmethod() = 0;
int test() ;
};

测试摘要.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;
}

派生类实现 DederdFromAbstract.h

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

衍生自摘要.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::d erivedTest() { cout <<"CDerivedFromAbstract::d erivedTest non-virtual function call from Derived" <<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_ */

对象接口.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 对象接口.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: In functionmain': main.cpp:(.text+0xe9): undefined reference totypeinfo for CDerivedFromAbstract' main.cpp:(.text+0xfe):未定义的引用 'CDerivedFromAbstract::d erivedTest()' collect2: error: ld 返回 1 退出状态

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

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

如果有人遇到此问题,请告诉我。我是 Linux 的新手,如果我缺少一些简单的概念,请告诉我。

谢谢

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

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

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

最新更新