최근에 custm CALLBACK의 함수 포인터에 문제가 생겼습니다. 문제는 임시적으로 문제를 해결하는 호출 규칙을 사용하기 시작했습니다. funy CALLBACK은 제대로 작동했지만 호출 함수의 서명은 여전히 잘못되었습니다! BUG을 찾아내는 데 많은 시간을 할애했습니다. 가 ... 규칙을 caling 것은 가끔 확인하지 무슨 일을 할 수 있다는 지난 지금 ... 지금, 나는이 규칙을 호출에 대한 저 작은 더 알고 싶어입니다표준 호출 규칙이 존재합니까?
확인을 실현 : 비주얼 스튜디오가 자신의 __cdecl
없는거야, __thiscall
등 (IIRC).
표준 C++은 일부 호출 규칙을 규정합니까? 그렇다면 어떻게 사용할 수 있습니까?
편집 :
이class Object;
class EventArgs;
typedef void(__cdecl Object::*MethodHandler)(Object* sender, EventArgs args);
///..... this is how I call it..(snapshot)
(iter->second.sender->*iter->second.memberFunct)(sender, args);
///...
void __cdecl Triger(EventArgs args) //missing "Object* sender" here!!! but it works!
{
if(args == "test")
cout << "test args received" << endl;
}
(. BTW, 유형 이름은 내 사용자 정의 클래스가) 그건 그냥 괜찮 았는데 : 일부 코드가있는 나는 버그를 찾지 못했습니다! 함수가 호출되었지만 __cdecl
없이 ESP 레지스터 오류가 발생했습니다.
버그가 무엇입니까? 일반적으로 컴파일러 오류없이 처리기/콜백을 등록하는 함수 포인터의 하드 코딩 된 캐스트는 잘못된 일을하는 데 드는 공짜입니다. 위의 코드에서 함수 인수가 다르므로 "트리거"는 MethodHandler 유형이 아닙니다. – selbie
감사합니다, 아니 그것은 동일한 서명 아니에요하지만 __cdecl을 사용하지 않는 경우 __cdelc를 사용하여 잘 작동합니다, 그리고 신 ESP 레지스터 오류 및 progrm chrush .. 매우 재미 있습니다 .. – codekiddy
당신이 안부와 운 좋게되고 있기 때문에 일하고 있어요 인수가 스택에 푸시되는 순서. cdecl 트릭은 아마도 충돌을 일으키지 않도록 스택을 마사지하는 것일뿐입니다. 어딘가에 코드에서 "(MethodHandler *) Trigger"(또는 void * cast)를 수행하여 컴파일 오류없이 해당 함수를 콜백 서비스에 등록합니다.캐스트를 사용하지 않고 코드를 컴파일하도록 코드를 수정하면 충돌이 사라집니다. 즉, 어디에서나 동일한 호출 규칙과 동일한 인수 목록을 의미합니다. – selbie