dll单元中封装了一个窗体,宿主程序调用该dll中的函数显示窗体,但是到最后关闭dll中窗体的时候就
报:“project XXX.exe raised too many consecutive exceptions:'access violation at 0x0303c06:read of 
address 0x0303c600'...” 断点调试跟踪不到,搞的快疯了!dll和宿主程序中加入 uses sharemem 也没有效果,
不知道是什么问题,刚开始的时候做了一个程序调用都没有问题,可以后来试了嵌入其他几个程序都报相同的错误。真是十分的不解!望有经验的帮忙,快急死了!

解决方案 »

  1.   

    从dll中传递的参数没有string类型的 都是pchar类型的。
      

  2.   

    没有涉及多线程,从dll中获取值然后传递给宿主程序。
      

  3.   

    问题找到了,改成静态调用就没有问题,我的dll文件中又静态调用了其他的两个dll这个可能是主要原因,但是我希望使用动态调用,以下是我的动态调用代码,高手指点一下:
    function _test(parray:pchar;var index:Integer;name:pchar):Integer;
    var
        myhandle,myhandle1,myhandle2:Thandle;
        myfunc:function (parray:pchar;var index:Integer;name:pchar):Integer;StdCall;
    begin
      result:=-1;
      myhandle1:=loadlibrary('1.dll');
      myhandle2:=loadlibrary('2.dll');
      myhandle:=loadlibrary('mydll.dll');
      if (myhandle<=0) then
      begin
        application.MessageBox('找不到 mydll.dll !','警告');
        exit;
      end;
      try
        @myfunc:=getprocaddress(myhandle,'test');    if (@myfunc <> nil) then
        begin
          result:=myfunc(parray,index,name);
        end;
      finally
        freelibrary(myhandle);
        freelibrary(myhandle1);
        freelibrary(myhandle2);
      end;
      

  4.   

    由于delphi的form封装时有application对象,而宿主程序和dll的application不同所以在宿主程序退出时会出错,所以在调用时应先把宿主的application传个dll,下面代码是写在丁零零里的,创建窗口前先运行这个.
    var
      DllApp:TApplication;{ 用于初始化:保存DLL本身的Application,然后设置DLL的Application指向Host的Application }
    procedure InitDLL(App:TApplication);stdcall;
    begin
      DllApp:=Application;
      Application:=App;
    end;{ 善后工作:恢复DLL原来的Application }
    procedure FreeDLL;stdcall;
    begin
      Application:=DllApp;
    end;
      

  5.   

    dll 中增加一个函数,
    比如
    freedll
    begin
     if assigned(form1) then
     begin
     form1.close; //dll单元中封装了一个窗体
     freeandnil(form1);
     end;
    end;在 freelibrary(myhandle);  前调用,是一个简单的解决方法
      

  6.   

    var
        myhandle,myhandle1,myhandle2:Thandle;
        myfunc:function (parray:pchar;var index:Integer;name:pchar):Integer;StdCall;
    begin
      result:=-1;
      myhandle1:=loadlibrary( '1.dll ');
      myhandle2:=loadlibrary( '2.dll ');
      myhandle:=loadlibrary( 'mydll.dll ');
      if (myhandle <=0) then
      begin
        application.MessageBox( '找不到 mydll.dll ! ', '警告 ');
        exit;
      end;
      try
        @myfunc:=getprocaddress(myhandle, 'test ');    if (@myfunc  < > nil) then
        begin
          result:=myfunc(parray,index,name);                                -------->这个里面是怎么显示窗体的?是Show还是ShowModal?
                                                                            ShowModal时是怎么Close?, 因为你接下来就FreeLibrary. 而静                  
                                                                            态调用时,宿主程序释放才释放LIB的。
        end;
      finally
        freelibrary(myhandle);
        freelibrary(myhandle1);
        freelibrary(myhandle2);
      end;
    BTW:很久不见阿日。