function StdWndProc(Window: HWND; Message, WParam: Longint;
  LParam: Longint): Longint; stdcall; assembler;
asm
        XOR     EAX,EAX
        PUSH    EAX
        PUSH    LParam
        PUSH    WParam
        PUSH    Message
        MOV     EDX,ESP
        MOV     EAX,[ECX].Longint[4]
        CALL    [ECX].Pointer  //执行类成员
        ADD     ESP,12  ?????不理解
        POP     EAX
end;我模仿该机制做了一个,实现了,但是函数执行完毕后总出现错误,帮我看看:
这是DLL中的:
class  //某类
……
P:Pointer  //类成员
procedure Test(g,l:longint); cdecl;
function GetP: Pointer; //返回P
……
end;
//Create中实现
P:= MyMakeObjectInstance(@TTest.Test);
//MyMakeObjectInstance只是修改了MakeObjectInstance中的一句:
Block^.WndProcPtr := Pointer(CalcJmpOffset(@Block^.Code[2], @StdInt));
//使用StdInt取代StdWndProc,实现如下:
procedure Test(g,l:longint); cdecl; assembler;
asm
  PUSH    l
  PUSH    g
  PUSH    EAX  //Self
  CALL    [ECX].Pointer
end;
//***********//
function test: Pointer;
var g:TTest;
begin
  g :=  TTest.Create;
  Result := g.getp;
end;exports test;然后在exe中调用Dll中Test返回的函数指针所指函数,预期的调用了TTest类中的Test成员过程,且在Test中使用类其他成员正常。最后还是返回读取内存地址错误。单步调试发现是在
类成员Test过程执行到函数end;后出错,即函数执行完毕后。
我对汇编不懂,也不懂保存现场什么的概念,希望高手指点。

解决方案 »

  1.   

    昨天晚上刚去学了汇编,问题已经解决。不会再有内存读取错误了。改这样
    procedure Test(g,l:longint); cdecl; assembler; 
    asm 
      PUSH    l 
      PUSH    g 
      PUSH    EAX  //Self 
      CALL    [ECX].Pointer 
      ADD     ESP,8 //因为上面压栈8字节  
    end; 
      

  2.   

    早上补习了下Delphi中的汇编对寄存器的默认约定,现在已经完全解决问题了。
    实现了在DLL外部调用DLL中类的成员方法或过程。不用回答了,不过CSDN怎么不能关闭问题?????
    提示24小时什么的,要密码,我输入正确后仍然没关闭该问题。