C++ GCC警告函数指针指向对象指针强制转换
显然,函数指针和对象指针之间的转换在一般意义上是未定义的行为,但是POSIX(请参阅:)和WinAPI(请参阅:)需要这样做 考虑到这一点,并且考虑到这样的代码无论如何都是针对特定于平台的API的,因此它在函数指针和对象指针不兼容的平台上的可移植性实际上是无关紧要的 但是-Wpedantic仍然会对此发出警告,C++ GCC警告函数指针指向对象指针强制转换,c++,gcc,c++11,mingw,gcc-pedantic,C++,Gcc,C++11,Mingw,Gcc Pedantic,显然,函数指针和对象指针之间的转换在一般意义上是未定义的行为,但是POSIX(请参阅:)和WinAPI(请参阅:)需要这样做 考虑到这一点,并且考虑到这样的代码无论如何都是针对特定于平台的API的,因此它在函数指针和对象指针不兼容的平台上的可移植性实际上是无关紧要的 但是-Wpedantic仍然会对此发出警告,#pragma GCC diagnostic ignored“-Wpedantic”没有任何效果: warning: ISO C++ forbids casting between poi
#pragma GCC diagnostic ignored“-Wpedantic”
没有任何效果:
warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [enabled by default]
我希望保持-Wpedantic处于启用状态,因为它确实提供了良好的警告,但我不希望在关于函数指针到对象指针强制转换的大量无关警告中丢失真正的警告和错误
有没有办法做到这一点
在Windows(MinGW)上运行GCC 4.8.0:
代码示例
#include <windows.h>
#include <iostream>
int main (void) {
std::cout << *reinterpret_cast<int *>(GetProcAddress(LoadLibraryA("test.dll"),"five")) << std::endl;
}
#包括
#包括
内部主(空){
std::cout始终可以使用memcpy技巧:
int (*f)() = 0;
int *o;
memcpy(&o, &f, sizeof(int*));
您可以在ideone上看到它:
至于您可能要采取的其他行动:一个明显的可能性是“修复”定义dlsym的头,以实际返回函数指针(如void(*)(
)。祝您好运。我想您可以在这里使用g++系统头
指令:
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
\ifndef wrap\u GetProcAddress\u包括在内
#定义包含的包裹地址
#pragma GCC系统头
模板
结果GetProcAddressAs([正常参数])
{
返回reinterpret_cast(GetProcAddressAs([正常参数]);
}
#恩迪夫
这很好用
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);
}
模板
作废*作废ptr(结果(*p)(参数…){
静态断言(sizeof(void*)==sizeof(void(*)(void)),
“对象指针和函数指针大小必须相等”);
void*q=&p;
返回*static_cast(q);
}
我从来没有在强制转换GetProcAddress
的结果时遇到过问题。您是否有生成警告的代码可以发布?@WhozCraig添加到问题中。test.dll
包含int-five=5
。编译和运行程序时只需打印“5”。这是一个有效的用例,它特别允许在运行时正常工作。使用extern“C”可以避免名称损坏问题
。编译器只有在编译时才对强制转换有问题。您至少应该声明函数指针足够大,可以容纳void*
。那么GetProcAddress
的问题就变成了,如果您想获取所加载库中不是函数的某个函数的地址,该怎么办D(参见添加到问题中的代码示例)?@ MARBB:假设OP想要使用POSIX,实际上,我会认为它是一个多余的杂波(类似于处理<代码> siZOF(char)不同于1)。但是如果您觉得需要它,可以添加它(在这种情况下,我宁愿把它放到AutoCONF脚本或SOMUUCH)中。.#pragma GCC system_header
。感谢您让我走上正轨。
#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
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);
}