我有一个共享库,它有一个具有纯虚函数的基类,还有一些实现派生类通用的函数。 基类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新手,如果我错过了一些简单的概念,请告诉我。
由于
答案 0 :(得分:0)
不,无法访问您通过 dlopen
导入的类中的非虚函数。
由于早期绑定,你调用的每个非虚函数都应该在编译时确定它的符号,而虚函数在运行时通过 vtable/vptr 搜索它的符号。如果你想在 main.cpp 中调用它,你应该声明 derivedTest
为 virtual。
查看此链接,该链接演示了通过 dlopen 加载类的详细示例:
C++ dlopen mini HOWTO