关于网友提出的“ 使用thunk出现异常。。”问题疑问,本网通过在网上对“ 使用thunk出现异常。。”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: 使用thunk出现异常。。
描述: 搜了些thunk原理,其中有一句话实在不理解,有人用过thunk吗? 以下是几个头文件和main.cpp,应该直接能编译运行,异常出现位置见下面代码中注释部分,请教这咋整,谢谢。
AJ_Thunk.h
#pragma pack(push,1)
struct AJ_Thunk {
DWORD _mov;
DWORD _this;
BYTE _jmp;
DWORD _relProc;
void init(DWORD proc, void* pThis) {
_mov = 0x042444C7;
_this = PtrToLong(pThis);
_jmp = 0xE9;
_relProc = DWORD((INT_PTR)proc - ((INT_PTR)this + sizeof(AJ_Thunk)));
FlushInstructionCache(GetCurrentProcess(), this, sizeof(AJ_Thunk));
}
};
#pragma pack(pop)
AJ_Window.h
//#include "AJ_Component.h"
#include
using namespace std;
#define AJ_UI_CLASS_NAME "xxxx"
#include "Thunk/AJ_Thunk.h"
LRESULT CALLBACK AJ_WndInitProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK AJ_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
class AJ_Window {
private:
int a;
public:
HWND hWnd;
AJ_Thunk* thunk;
ATOM registerClass() {
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = AJ_WndInitProc;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = NULL ;
wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ) ;
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ) ;
wndclass.hbrBackground = ( HBRUSH ) GetStockObject( WHITE_BRUSH ) ;
wndclass.lpszMenuName = "" ;
wndclass.lpszClassName = AJ_UI_CLASS_NAME;
wndclass.hbrBackground = HBRUSH(COLOR_WINDOW ) ;
return RegisterClass(&wndclass);
}
AJ_Thunk* createThunk() {
thunk = new AJ_Thunk;
thunk->init((DWORD)AJ_WndInitProc, this);
return thunk;
}
void showError() {
}
MSG msg;
void wait() {
while(GetMessage( &msg, NULL, 0, 0 )){
TranslateMessage( &msg ) ;
DispatchMessage( &msg ) ;
}
}
AJ_Window() : hWnd(NULL), a(9) {
this->registerClass();
string title = "aj window";
CreateWindow(
AJ_UI_CLASS_NAME,
title.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT ,
CW_USEDEFAULT ,
//width ? width : 480,
//height ? height :260,
300,200,
NULL,
NULL,
NULL,
this ) ;
if(hWnd == NULL) {
this->showError();
}
}
WNDPROC getThunk() {
return (WNDPROC)thunk;
}
~AJ_Window() {
delete thunk;
}
void show() {
ShowWindow(hWnd, true);
}
void hide() {
ShowWindow(hWnd, false);
}
void updateWindow() {
::UpdateWindow(hWnd);
}
void onPaint() {
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 10, 10, "tttt", 4);
EndPaint(hWnd, &ps);
}
void onDestory() {
PostQuitMessage(0);
}
};
LRESULT CALLBACK AJ_WndInitProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if(msg == WM_NCCREATE) {
AJ_Window* win = (AJ_Window*)((LPCREATESTRUCT)lParam)->lpCreateParams;
win->hWnd = hWnd;
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)win->createThunk());
WNDPROC thunk = win->getThunk();
return (*thunk)(hWnd, msg, wParam, lParam); // 就这个地方异常
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
LRESULT CALLBACK AJ_WndProc(HWND hWnd, UINT msg, UINT wParam, UINT lParam) {
AJ_Window* pWindow = (AJ_Window*)hWnd;
switch(msg){
case WM_PAINT:
pWindow->onPaint();
break;
case WM_DESTROY:
pWindow->onDestory();
break;
default:
return DefWindowProc( hWnd, msg, wParam, lParam ) ;
}
return 0;
}
main.cpp
#include
#include "AJ_Window.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
AJ_Window* win = new AJ_Window();
win->show();
win->wait();
return 0;
}
解决方案1: thunk是在虚继承时为了维护徐函数表用的技术,依赖编译器实现不同。
不明白你这里也拿来用了,既然都是windows,封装现有的问题不大吧,可移植性应该好点。
解决方案2: 楼上说的对,不能用new,且thunk必须是类的第一个数据成员。
VC6和VC2008出现差异没碰到过,倒是因为WIN2003的数据执行保护会导致非法操作。
关于thunk更详细的说明请看这里:http://blog.csdn.net/ringphone/archive/2004/09/28/118883.aspx
不过这篇文章里的代码不能在WIN2003下运行,可运行的版本请到我博客下载RingSDK看里面的代码。
解决方案3: 应该是
AJ_Thunk* getThunk() {
if(!thunk) {
thunk = new AJ_Thunk;
thunk->init((DWORD)AJ_WndProc, this);
}
return thunk;
}
估计是new的问题
试试使用VirtualAlloc之类的API分配内存
解决方案4: http://blog.csdn.net/lqk1985/archive/2009/11/10/4791304.aspx
这绝对是对于新手的误导,这样的代码很大程度上依赖于编译器。不能称之为“技术”。谁能保证编译器每次生成的目标代码都一样?而且编译器在编译的时候会对代码进行优化,那就更不知道生成的目标代码是什么样子了。
解决方案5:
那还不如直接包装CWnd等类来得方便,简单,你用这种方法很容易有问题..以后维护也痛苦
解决方案6: 不明白您的代码到底是出于什么目的,需要这样去写?
这种东西与编译器有很大的关系,我们不能想当然的认为编译器一定会按我们的想法去编译程序。
以上介绍了“ 使用thunk出现异常。。”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/2405031.html