我正在尝试从 DLL 调用函数。该 DLL 的 API 如下所示:
#pragma once
#include <stdint.h>
#include <stdbool.h>
#if defined _MSC_VER || defined __MINGW32__
#ifdef __cplusplus
#define API extern "C" __declspec(dllexport)
#else
#define API __declspec(dllexport)
#endif
#else
#ifdef __cplusplus
#define API extern "C" __attribute__((visibility("default")))
#else
#define API __attribute__((visibility("default")))
#endif
#endif
API void* construct(const char* initString);
我正在使用 boost 加载该函数调用,然后尝试调用它:
#include <boost/dll/import.hpp>
#include <boost/function.hpp>
#include <boost/filesystem.hpp>
#include <iostream>
typedef void* (ConstructT)(const char*);
int main() {
boost::function<ConstructT> constructFunc = boost::dll::import_alias<ConstructT>(
"TestPluginDll.dll",
"construct",
boost::dll::load_mode::append_decorations | boost::dll::load_mode::load_with_altered_search_path
);
std::string initArg = "hello";
void* pluginInstance = constructFunc(initArg.c_str());
std::cout << pluginInstance << std::endl;
}
但是,调用时失败constructFunc
,并在以下代码中引发错误boost/dll/import.hpp
:
// Compilation error at this point means that imported function
// was called with unmatching parameters.
//
// Example:
// auto f = dll::import_symbol<void(int)>("function", "lib.so");
// f("Hello"); // error: invalid conversion from 'const char*' to 'int'
// f(1, 2); // error: too many arguments to function
// f(); // error: too few arguments to function
template <class... Args>
inline auto operator()(Args&&... args) const
-> decltype( (*f_)(static_cast<Args&&>(args)...) )
{
return (*f_)(static_cast<Args&&>(args)...);
}
为什么会失败? 的类型std::string.c_str()
是const char*
,因此看起来它是正确的类型。
作为参考,我的 DLL 代码如下所示:
#include <plugin_interface.hpp>
#include <iostream>
#include <nlohmann/json.hpp>
class MyPlugin {
public:
MyPlugin() {}
};
extern "C" API void* construct(const char* initString) {
MyPlugin* plugin = new MyPlugin();
return static_cast<void*>(plugin);
}
例外情况:
Exception has occurred: W32/0xC0000005
Unhandled exception at 0x00007FF77B713633 in tmp.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
14
最佳答案
2
经过进一步调查,我意识到 boost 实际上是按预期工作的。问题是由 的错误使用引起的boost::dll::import_alias
。它应该只与通过BOOST_DLL_ALIAS
宏从库中导出的特殊符号一起使用。alias
在此上下文中是全局命名空间中的一个变量,其纯名称包含指向实际导出的深层嵌套函数的指针。请参阅
#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
#include "../tutorial_common/my_plugin_api.hpp"
namespace my_namespace {
class my_plugin_aggregator : public my_plugin_api {
float aggr_;
my_plugin_aggregator() : aggr_(0) {}
public:
std::string name() const {
return "aggregator";
}
float calculate(float x, float y) {
aggr_ += x + y;
return aggr_;
}
// Factory method
static boost::shared_ptr<my_plugin_aggregator> create() {
return boost::shared_ptr<my_plugin_aggregator>(
new my_plugin_aggregator()
);
}
};
BOOST_DLL_ALIAS(
my_namespace::my_plugin_aggregator::create, // <-- this function is exported with...
create_plugin // <-- ...this alias name
)
} // namespace my_namespace
由于construct
它只是全局命名空间中的常规函数,因此可以使用boost::dll::import_symbol
boost::function<ConstructT> constructFunc = boost::dll::import_symbol<ConstructT>(
"TestPluginDll.dll",
"construct",
boost::dll::load_mode::append_decorations | boost::dll::load_mode::load_with_altered_search_path
);
1
-
感谢更新,我
BOOST_DLL_ALIAS
之前用的是,但我不得不改用与 C 兼容的 API,而且我不知道我必须改用 import_symbol
–
|
除了@user7860670指出的错误限制之外,这个typedef是不正确的:
typedef void* (ConstructT)(const char*);
它需要一个extern "C"
。 。
extern "C" {
typedef void* (ConstructT)(const char*);
}
虽然在实践中,省略语言链接可能在许多工具链上起作用,但在形式上,它。
|
–
–
dllPath
?它是相对路径吗?并且 DLL 不在您所期望的位置?如果您使用完整的绝对路径,那么它会起作用吗?–
–
–
|