在Delphi中,新建一个Application,在Dpr单元写个最简单的单元,用Exports也能输出这个函数。
用PE分析软件也能在Exe文件的输出表中找到该输出函数。但是在另外一个Exe文件中,把它当Dll调用(静态或动态调用),都返回不了正确结果呢?

解决方案 »

  1.   

    根据网上找到的文章,测试程序如下:(但没成功)
    ==========================调用程序代码==========================
    procedure TfrmMainExe.Button1Click(Sender: TObject);
    var
      lib: THandle;
      Test: procedure(p: PChar); stdcall;
    begin
      //
      lib := LoadLibrary('ExeDll.exe');
      if lib = 0 then
      begin
        ShowMessage('Error LoadLibrary!');
      end
      else
      begin
        @Test := GetProcAddress(lib, 'Test');
        if @Test = nil then
        begin
          ShowMessage('Error GetProcAddress!');
        end
        else
        begin
          try
            Test('这是一个测试!');
          except
            ShowMessage('Error Execute!');
          end;
        end;
        FreeLibrary(lib);
      end;
    end;
    ===============================ExeDll代码(是Program)====================
    program ExeDll;uses
      Forms,
      Windows,
      Main in 'Main.pas' {frmMainDll};{$R *.res}procedure Test(p: PChar); export; stdcall;
    begin
      MessageBox(0, p, '系统提示', MB_OK);
    end;exports
      Test;begin
      Application.Initialize;
      Application.CreateForm(TfrmMainDll, frmMainDll);
      Application.Run;
    end.
      

  2.   

    在Win2k(SP4) + D6下,在
    Test('这是一个测试!');
    报内存访问错!
    ===============
    我原来的程序,返回错误空串!
      

  3.   

    另开新贴在
    http://community.csdn.net/Expert/topic/4256/4256848.xml?temp=.3997919
      

  4.   

    帮你测试了一下,没问题啊。把邮箱留下,我把测试demo发给你啊
      

  5.   

    诶?我用你的这个输出函数测试没有问题。
    procedure Test(p: PChar); export; stdcall;
    begin
      MessageBox(0, p, '系统提示', MB_OK);
    end;我把messagebox改成showmessage就出现错误。晕,不懂,查查资料先。
      

  6.   

    [email protected]
    [email protected]
    谢谢!
    ========================
    我先做了个程序,不通过。
    查资料,找到如上代码,重新开始,测试仍不通过。
    会不会是哪的什么编译选项问题!
      

  7.   

    谢谢,已经收到了!
    我用你发过来的Exe运行,可以通过!
    但我用D6重新Build了一下,就出问题了!而且里面的Try Except也很怪,跟平时的不一样。
    一般Try Except会报个内存错误,再执行Except里的内容。
    但这次报不一样,它直接在Test('内存错误!')这个地方按了F8就执行了Except了。
    我估计是与FarProc有关。
    但为什么D6重新编译后就不过,不知道为什么?
    今天晚上回去用D7编了再看看?
      

  8.   

    不过自己LoadLibrary自己以后,也能调用成功的!
    不知道为什么其他Exe调用会出问题!
      

  9.   

    我把输出函数改成beep也是内存错误。晕
      

  10.   

    我估计是得到的输出函数地址,在主Exe中的指向就不对了!
      

  11.   

    回去试了把,在D7下,用messagebox没问题,用其他的就出问题了!
    另经测试,在exedll中,用
    with TfrmMain.Create(nil) do
    try
      ShowModal;
    finally
      Free;
    end;
    显示出来的不是exedll中的主界面,而是调用他的exe文件的主界面,而且一点弹出来的窗体被关闭后,就报错。
      

  12.   

    我用BCB测试了一把,
    还是不行,
    可以找到函数入口,
    但是地址好象指错了。
      

  13.   

    看来EXE的输出表是没法用了!
      

  14.   

    我想,问题可能出在Borland自身的实现机理上与Windows执行原理的冲突上。如果查看Borland提供的Rtl源代码,可以看到,Delphi在每个EXE工程的开始处都保留了自己的句柄、内存空间、以及重定位了一些全局函数。
    但是,根据Windows的执行原理,调用的DLL与调用者处在同一平坦内存区域,内存中所有全局性的东西是共用的,而不是各自有所保留。
      

  15.   

    个人认为,应该是Application.Handle的问题,当作为Exe直接运行的时候,会产生新的Application.Handle,所以你的MessageBox可以正确执行,而当作Dll运行的时候,不会生成新的Application.Handle,而MessageBox是Application的方法,既然没有Application,那么肯定会有问题的,你可以把主调用程序的Handle传递进去试试吧。=============================================================================
    声明:本人绝对不是高手,最多是一个低手,以上只是胡说几句,对就对,错了也不要笑话!祝好运……
      

  16.   

    昨天试了下,把application传进去,也报错!