2013-04-15 5 views
10

함수 포인터와 객체 포인터 사이의 캐스트는 일반적으로 정의되지 않은 동작이지만 POSIX (참조 : dlsym 참조) 및 WinAPI (참조 : GetProcAddress 참조)에는이 기능이 필요합니다. GCC가 함수 포인터에 관해 경고합니다.

이를 감안할 때, 이러한 코드는 함수 포인터와 객체 포인터는 정말 관련이 호환되지 않는 플랫폼으로, 어쨌든 이동성을 플랫폼 고유의 API를 목표로하고 있다는 사실을 주어진.

그러나 어쨌든 그것에 대해 경고 -Wpedantic 및 #pragma GCC diagnostic ignored "-Wpedantic" 아무런 효과가 없습니다 : 나는 그것이 좋은 경고를주지 않기 때문에 -Wpedantic이 활성화 유지하려는

warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [enabled by default] 

을,하지만 난 싶지 않아 실제 경고 및 오류가 객체 포인터 캐스트에 대한 함수 포인터와 관련이없는 경고의 바다에서 사라지도록하는 것입니다.

이 작업을 수행 할 수있는 방법이 있나요? (-Wpedantic와)

gcc (rubenvb-4.8.0) 4.8.0 

코드 샘플

#include <windows.h> 
#include <iostream> 


int main (void) { 

    std::cout << *reinterpret_cast<int *>(GetProcAddress(LoadLibraryA("test.dll"),"five")) << std::endl; 

} 

방출 :

warning_demo.cpp: In function 'int main()': 
warning_demo.cpp:7:87: warning: ISO C++ forbids casting between pointer-to-funct 
ion and pointer-to-object [enabled by default] 
    std::cout << *reinterpret_cast<int *>(GetProcAddress(LoadLibraryA("test.dll"), 
"five")) << std::endl; 

    ^
+0

'GetProcAddress' 결과를 캐스팅하는 데 전혀 문제가 없었습니다. – chris

+2

게시 할 수있는 경고를 생성 한 * 코드 *가 있습니까? – WhozCraig

+0

@WhozCraig 질문에 추가됨. –

답변

3

나는 당신 ++의 여기 system_header 지시어를 g을 사용할 수 있습니다 생각합니다.

template <typename RESULT, typename ...ARGS> 
void * make_void_ptr(RESULT (*p)(ARGS...)) { 
    static_assert(sizeof(void *) == sizeof(void (*)(void)), 
        "object pointer and function pointer sizes must equal"); 
    void *q = &p; 
    return *static_cast<void **>(q); 
} 
+0

'#pragma GCC system_header'. 저를 올바른 길로 인도 해 주셔서 감사합니다. –

2

가있어 윈도우 (는 MinGW)에 GCC 4.8.0을 실행

항상 사용할 수있는 memcpy 트릭 :

int (*f)() = 0; 
int *o; 
memcpy(&o, &f, sizeof(int*)); 

ideone : m is generating warnings, while g is OK에서 볼 수 있습니다.

다른 조치 방법에 대해서는 다음과 같이 취할 수 있습니다. dlsym을 정의하는 헤더를 "수정"하여 실제로 함수 포인터 (예 : void (*)())를 반환하는 것이 좋습니다. 좋은 결과 내길 바랄 게.

wrap_GetProcAddress.h가 :

#ifndef wrap_GetProcAddress_included 
#define wrap_GetProcAddress_included 

#pragma GCC system_header 

template <typename Result> 
Result GetProcAddressAs([normal parameters]) 
{ 
    return reinterpret_cast<Result>(GetProcAddressAs([normal parameters])); 
} 

#endif 
+0

함수 포인터가'void *'를 담을만큼 충분히 커서 static_assert해야합니다. –

+0

그러면'GetProcAddress'의 문제는로드 한 라이브러리의 함수가 아닌 주소를 얻고 자 할 때 어떻게됩니까? (질문에 추가 한 코드 예를 참조하십시오)? –

+1

@ MarkB : OP가 POSIX를 사용하기를 원한다는 사실을 감안할 때 실제로 [객체 포인터와 같은 표현을 갖는 함수 포인터가 필요합니다] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html) # tag_15_12), 나는 그것이 불필요한 혼란 (1과 다른'sizeof (char) '취급과 유사)이라고 생각할 것이다. 하지만 필요하다고 생각되면 추가 할 수 있습니다 (이 경우 autoconf 스크립트에 넣으려고합니다). – jpalecek

3

이 잘 작동

관련 문제