rcv*_*rcv 12 c++ function-pointers shared-libraries c++11
我正在尝试围绕dlopen()/ dlsym()编写一个C++ 0x包装器,以动态加载共享对象中的函数:
class DynamicLoader
{
public:
DynamicLoader(std::string const& filename);
template<class Signature>
std::function<Signature> load(std::string const& functionName);
private:
void *itsLibraryHandle;
};
DynamicLoader::DynamicLoader(std::string const& filename)
{
itsLibraryHandle = dlopen(filename.c_str(), RTLD_LAZY);
if(!itsLibraryHandle)
{ /* Throw Some Error */ }
}
template<class Signature>
std::function<Signature> DynamicLoader::load(std::string const& functionName)
{
return <insert magic here> dlsym(itsHandle, functionName.c_str());
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将dlsym返回的void*函数指针转换为std :: function?
试试这个:
static_cast<Signature*>()
Run Code Online (Sandbox Code Playgroud)
似乎在VC10中有效
完整测试:
#include <functional>
void test()
{}
template <typename Signature>
std::function<Signature> cast(void* f)
{
return static_cast<Signature*>(f);
}
int main()
{
std::function<void()> f = cast<void()>(&test);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据我在这里看到的内容:http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html
#include <boost/function_types/components.hpp>
#include <boost/function_types/function_pointer.hpp>
template< typename Signature >
std::function<Signature> DynamicLoader::load(std::string const& name)
{
namespace ft = boost::function_types;
typedef typename ft::function_pointer< typename ft::components<Signature>::type >::type fp_t;
fp_t fun_ptr;
*reinterpret_cast<void**>(&fun_ptr) = dlsym(itsHandle, name.c_str());
return fun_ptr;
}
Run Code Online (Sandbox Code Playgroud)
我从来没有使用过dlsym所以我不明白为什么演员阵容是这样做的而不是像这样简单地投射dlsym的回报:
fun_ptr = reinterpret_cast<fp_t>(dlsym(itsHandle, name.c_str());
Run Code Online (Sandbox Code Playgroud)