присваивание функций std :: function с одной и той же сигнатурой, но другое соглашение о вызовах не выполняется

следующий компилируется и прекрасно работает с флагами mingw 4.7.2 и -m64.

но с -m32 или с любым 32-разрядным выпуском mingw он не скомпилируется. это ошибка или мне не хватает флага компилятора?

    #include <iostream>
#include <functional>

using namespace std;

int __cdecl ccall(int i)
{
cout << i << endl;
return 0;
}

int __stdcall stdcall(int i)
{
cout << i << endl;
return 0;
}

int __fastcall fastcall(int i)
{
cout << i << endl;
return 0;
}int main() {

std::function<int(int)> fnc = ccall;
fnc(10);

std::function<int(int)> fnstd = stdcall;
fnstd(100);

std::function<int(int)> fnfast = fastcall;
fnfast(200);

return 0;
}

сообщение об ошибке:

    ...\Local\Temp\cc4ekW9J.s: Assembler messages:
...\Local\Temp\cc4ekW9J.s:30: Error: symbol `__ZNSt17_Function_handlerIFiiEPFiiEE9_M_invokeERKSt9_Any_datai' is already defined
...\Local\Temp\cc4ekW9J.s:80: Error: symbol `__ZNSt14_Function_base13_Base_managerIPFiiEE10_M_managerERSt9_Any_dataRKS4_St18_Manager_operation' is already defined
...\Local\Temp\cc4ekW9J.s:114: Error: symbol `__ZNSt14_Function_base13_Base_managerIPFiiEE10_M_managerERSt9_Any_dataRKS4_St18_Manager_operation' is already defined

я закончил тем, что делал это таким образом после того, как «скрыл» вызов в лямбда-функции, она работает просто отлично:

    template<class Ret, class... Args> class StdCall
{
public:
typedef Ret(__stdcall Fn_t)(Args...);
typedef std::function<Ret (Args...)> Functor_t;
Functor_t get(Fn_t pFn)
{
return [pFn](Args... as){
return pFn(as...);
};
}
};

auto fn1 = CdeclCall<int,int>().get( ccall );
auto fn2 = StdCall<int,int>().get( stdcall );

fn1(123);
fn2(156);

2

Решение

Считай, что тебе повезло. Подумайте о том, какой хаос может вызвать вызов функции с неправильным соглашением о вызовах! Да, и просто создайте функцию shim с «правильным» соглашением о вызовах, которое вызывает «неправильное». Возможно, вы можете скрыть это в отдельно скомпилированном файле.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector