C/C++에서 작성한 두 개의 프로젝트가있었습니다. 프로젝트 1 출력은 exe 파일이며 MyProject입니다. 프로젝트 2 출력은 dll 파일이며 Bridge라는 이름입니다. Bridge에서 MyProject의 기능을 실행하도록합니다. 함수가 작동하는 것처럼 보이지만 오류가 발생했습니다.런타임 검사 실패 # 0 오류가있는 DLL을 통해 함수 포인터가있는 콜백 함수
"런타임 점검 오류 # 0 - ESP 값이 함수 호출을 통해 올바르게 저장되지 않았습니다. 이것은 일반적으로 하나의 호출로 선언 된 함수를 호출 한 결과입니다 관례는 다른 호출 규칙으로 선언 된 함수 포인터를 가지고 있습니다. "
근본 원인이 __cdecl __stdcall 규칙에서 발생할 수는 있지만 여전히 해결 방법을 알지는 못합니다. 모든 프로젝트의 호출 규칙 설정 (/ 하나님) __cdecl, 그리고 VS IDE는 VS 2013입니다
DLL 프로젝트 (다리) 코드
헤더
typedef void(*sfcTrace)(const char *logLevel, const char *logMessage);
class OnRequestHandler
{
public:
virtual void writeLog(sfcTrace callback) = 0;
};
class GenericInfoHandler : public OnRequestHandler
{
public:
GenericInfoHandler();
~GenericInfoHandler() { delete this; };
void writeLog(sfcTrace callback);
};
extern "C" __declspec (dllexport) OnRequestHandler* __cdecl oneBridgeCallBack()
{
return new GenericInfoHandler;
}
CPP
void GenericInfoHandler::writeLog(sfcTrace callback)
{
const char *level = "DEBUG";
const char *message = "TEST";
callback(level, message);
}
MyProject 소스 코드 :
MyProject를에서3210typedef OnRequestHandler* (__cdecl *test)();
HINSTANCE getDLL = LoadLibrary("Bridge.dll");
if (!getDLL)
{
cout << "Cannot not load DLL." << endl;
}
test func = (test)::GetProcAddress(getDLL, "oneBridgeCallBack");
if (!func)
{
cout << "Cannot not locate the function." << endl;
}
OnRequestHandler* instance = func();
instance->writeLog(&MyProject::TestCallBack); <----- Error Occurs here
기능 구현
void MyProject::TestCallBack(const char *level, const char *message)
{
if (strcmp(level, "INFO") == 0){
// do something
}
else if (strcmp(level, "DEBUG") == 0){
// do something
}
}
헤더 :
typedef void(MyProject::*TestCallBack)(const char *logLevel, const char *logMessage);
class OnRequestHandler
{
public:
virtual void writeLog(sfcTrace callback) = 0;
};
class GenericInfoHandler : public OnRequestHandler
{
public:
GenericInfoHandler();
~GenericInfoHandler() { delete this; };
void writeLog(sfcTrace callback);
};
콜백에 대한 호출 규칙을 명시 적으로 지정하십시오. 'typedef void (__ cdecl * sfcTrace) (const char * logLevel, const char * logMessage);' – lockcmpxchg8b
또한 MyProject는 네임 스페이스입니까? (나는 네임 스페이스를 가정하고, 그렇지 않으면 콜백에 대한 포인터 - 투 - 멤버 함수를 전달하는 것에 대한 컴파일러 경고를 기대할 것이다.) – lockcmpxchg8b
Thx, 그리고 MyProject는 클래스이다. MyProject 클래스에서 TestCallBack 함수를 구현하고 TestCallBack의 주소를 전달하고 DLL writeLog를 호출하도록했습니다. – user3738211