我有一个共享库,它有一个基类,该基类具有纯虚函数,并且实现了更多派生类通用的函数。 基类 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 function
main': main.cpp:(.text+0xe9): undefined reference to
typeinfo 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