Я пытаюсь написать обертку C ++ 0x вокруг dlopen () / dlsym () для динамической загрузки функций из общих объектов:
class DynamicLoader { public: DynamicLoader(std::string const& filename); template std::function 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 std::function DynamicLoader::load(std::string const& functionName) { return dlsym(itsHandle, functionName.c_str()); }
Есть ли способ преобразовать указатель функции void *, возвращаемый dlsym в функцию std ::?
попробуй это:
static_cast()
похоже работает в VC10
полный тест:
#include void test() {} template std::function cast(void* f) { return static_cast(f); } int main() { std::function f = cast(&test); return 0; }
Основываясь на том, что я вижу здесь: http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html
#include #include template< typename Signature > std::function DynamicLoader::load(std::string const& name) { namespace ft = boost::function_types; typedef typename ft::function_pointer< typename ft::components ::type >::type fp_t; fp_t fun_ptr; *reinterpret_cast(&fun_ptr) = dlsym(itsHandle, name.c_str()); return fun_ptr; }
Я никогда не пользовался dlsym, поэтому я не понимаю, почему актеры делаются именно так, а не просто бросают dlsym так:
fun_ptr = reinterpret_cast(dlsym(itsHandle, name.c_str());
Вам просто нужно передать результат вызова dlsym () в соответствующий тип. Вот полный рабочий пример:
#include #include #include #include #include class DynamicLoader { public: DynamicLoader(std::string const& filename) : m_handle(dlopen(filename.c_str(), RTLD_LAZY)) { if (!m_handle) { throw std::logic_error("can't load library named \"" + filename + "\""); } } template std::function load(std::string const& functionName) const { dlerror(); void* const result = dlsym(m_handle, functionName.c_str()); if (!result) { char* const error = dlerror(); if (error) { throw std::logic_error("can't find symbol named \"" + functionName + "\": " + error); } } return reinterpret_cast(result); } private: void* const m_handle; }; int main() { DynamicLoader const loader("/lib64/libz.so.1"); auto const zlibVersion = loader.load("zlibVersion"); std::cout << "zlib version: " << zlibVersion() << std::endl; return 0; }