簡體   English   中英

函數指針賦值在C中有效但不在C ++中

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM