[英]Function Pointer assignment works in C but not C++
我需要在運行時在Mac OS X中動態鏈接到庫函數。在Apple的示例之后 ,我聲明了一個函數指針並為其指定了dlsym()的結果。 以下示例成功編譯為普通C(.c)文件。 但我需要在C ++文件中使用它,如果我將此示例編譯為C ++文件(.cpp),則clang編譯器會告訴我
無法使用'void '類型的右值初始化'void( )(char *)' 類型的變量
為什么它在簡單的'C'中工作,我該如何解決這個問題?
#include <dlfcn.h>
void Test() {
// Load the library which defines myFunc
void* lib_handle = dlopen("myLib.dylib", RTLD_LOCAL|RTLD_LAZY);
// The following line is an error if compiled as C++
void (*myFunc)(char*) = dlsym(lib_handle, "myFunc");
myFunc("Hello");
dlclose(lib_handle) ;
}
dlsym
返回void*
。 在POSIX中(但不是標准C,正如James所指出的那樣)有一個從void*
到指向函數類型的隱式轉換,因此對myFunc
的賦值才有效。 在C ++中沒有隱式轉換(因為它不是類型安全的),所以你需要通過添加一個強制轉換來告訴編譯器你真正的意思:
void (*myFunc)(char*) = (void(*)(char*))dlsym(lib_handle, "myFunc");
(或者您可以通過reinterpret_cast
獲得幻想)。
因為C編譯器壞了。 void*
和指向函數的指針之間沒有轉換(顯式或隱式),無論是在C還是在C ++中。
Posix為C添加了一個限制,並要求void*
和指向函數的指針具有相同的大小和表示,以便:
void (*myFunc)( char * );
*(void (**myFunc)( char* ))( &myFunc ) = dlsym(...);
將工作。
在C ++中,您可能希望使用以下內容:
class GetFunctionHelper;
GetFunctionHelper getFunction( void* dlHandle, std::string const& functionName );
class GetFunctionHelper
{
void* fromSystem;
freind GetFunctionHelper getFunction( void* , std::string const& );
GetFunctionHelper( void* fromSystem ) : fromSystem( fromSystem ) {}
public:
template <typename Ptr> operator Ptr() const
{
return *reinterpret_cast<Ptr const*>( &fromSystem );
}
};
GetFunctionHelper
getFunction( void* dlHandle, std::string const& functionName )
{
return GetFunctionHelper( dlsym( dlHandle, functionName.c_str() ) );
}
(當然還有更多的錯誤檢查)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.