问题描述
我需要在运行时加载一个 DLL。我事先不知道要加载哪个 DLL,但 DLL 是接口的实现(纯虚方法)。最终目标是有一个指向 DLL 的指针来调用它的方法。
现在,我只想测试 DLL 加载,调用测试方法,但我失败了。测试方法是void test()
。
#if defined (_WIN32)
const path PluginExtension(".dll");
#define STDCALL __stdcall
#else
const path PluginExtension(".so");
#define STDCALL
#endif
extern "C"
{
typedef void* (STDCALL* CreatorFunction)();
constexpr auto FunctionName{ "CommandGeneratorEngine::Interface::test" };
}
auto library = LoadLibraryExW(pluginPath.native().c_str(),nullptr,LOAD_WITH_ALTERED_SEARCH_PATH);
if (library != nullptr) {
auto creator = (CreatorFunction)GetProcAddress(library,FunctionName);
if (creator != nullptr) {
// do something
}
else
{
throw std::exception("Error when loading comm plugin");
}
界面
namespace TGComm {
namespace CommandGeneratorEngine {
class Interface {
public:
using Ptr = std::shared_ptr<Interface>;
virtual ~Interface() = default;
virtual void test() = 0;
};
}
}
以及接口实现:
class LHFImplementationInterface : public CommandGeneratorEngine::Interface
{
public:
void __declspec(dllexport) __stdcall test() override{
// do something...
}
};
线
auto creator = (CreatorFunction)GetProcAddress(library,FunctionName);
返回空值。
解决方法
解决了。
我创建了一个新的头文件,h1.h
#include "Global.h"
extern "C" {
LHCOMMQT_LIB void* createTGCommPlugin();
}
它的 cpp 是
#include "h1.h"
#include "LHFImplementationinterface.h"
void* createTGCommPlugin() {
auto p = new LHFImplementationInterface();
return p;
}
和 global.h 是
#ifndef LHCOMM_GLOBAL_H
#define LHCOMM_GLOBAL_H
#include <QtCore/qglobal.h>
#ifdef LHCOMMQT_EXPORTS
# define LHCOMMQT_LIB Q_DECL_EXPORT
#else // ifdef LHCOMMQT_EXPORTS
# define LHCOMMQT_LIB Q_DECL_IMPORT
#endif // ifdef LHCOMMQT_EXPORTS
#endif // LHCOMM_GLOBAL_H
主要内容:
typedef void* (STDCALL* CreatorFunction)();
constexpr auto FunctionName{ "createTGCommPlugin" };
try {
auto library = LoadLibraryExW(pluginPath.native().c_str(),nullptr,LOAD_WITH_ALTERED_SEARCH_PATH);
if (library != nullptr) {
auto creator = (CreatorFunction)GetProcAddress(library,FunctionName);
...
现在效果很好