首先,这个pb.dll是用pb写的,我这边的.net通过dllimport重新封装成一个新的dll,比如命名为A.dll。
其次,我有一个解决方案Solution,引用有很多dll子模块,分别为S_A.dll、S_B.dll等,也包括A.dll。
然后,我在solution解决方案里调用A.dll里的初始化函数,初始化成功未报错。
接着,我的子模块S_A.dll里的一个页面调用A.dll里的一个方法,得到的结果是A.dll里相关的界面显示,但是相应的数据未返回。如果,我在子模块S_A.dll里对A.dll进行初始化,那么同样的调用A.dll里的方法,得到的结果却是界面跟数据都有。想了很久,搞不明白,求神人指教,或者给思路,谢谢。好的答案思路追分。

解决方案 »

  1.   

    一.在DLL中创建Form  
     1.一步,创建DLL工程,及加入设置好的Form  
     library  MGRPERSN;  
     uses      SysUtils,  Classes,  
       MGRPERFM  in  'MGRPERFM.pas'  {FormPERSON};//1.Form的代码(与一般的Form一样)  
     {$R  *.RES}  
     exports  
         ShowPerSN;//2.函数输出口定义  
     begin  
     end.  
     2.  在DLL设定的Form的设置    
     unit  MGRPERFM;  
     interface  
     uses  Windows,  Messages,  SysUtils,  Classes,  Graphics,  Controls,  Forms,  Dialogs,  
       ComCtrls,  ToolWin,  ImgList;  
     type  
       TFormPERSON  =  class(TForm)  
       private  
           {  Private  declarations  }  
       public  
           {  Public  declarations  }  
       end;  
     //些处的变量不再用,给其改个地方,如下(改变之一)  
     //var    FormPERSON:  TFormPERSON;  
     {  Declare  the  export  function  宣布Form函数出口}//改变之二  
     function  ShowPerSN(AHandle:  THandle;  ACaption:  String):BOOL;  StdCall;  
     implementation  
     {$R  *.DFM}      //函数据过程定义  
     function  ShowPerSN(AHandle:  THandle;  ACaption:  String):BOOL;  
     var      FormPERSON:  TFormPERSON;  //定义窗体类(上面的放到了此处)  
     begin  
     //拷贝应用程式句柄给DLL的应有程式对象  
       Application.Handle  :=  AHandle;  
       FormPERSON  :=  TFormPERSON.Create(Application);//创建控件TForm  
       try  
           FormPERSON.Caption  :=  ACaption;  
           FormPERSON.ShowModal;//显示此Form              
           Result  :=  False;  //反回成功值  
       finally  
           FormPERSON.Free;  
       end;  
     end;  
     二.DLL中函数及窗体的调用  
     1.调用方法一  
     implementation  //在此的下方写明调用函数的DLL  
     {$R  *.DFM}//DLL内函数调用  
     function  PenniesToSoins(SourceResult:Integer):Integer;    StdCall  external  'FIRSTDLL.DLL';  
     2.调用方法二  
     type    //在此创建一个函数类  
     {  First,  define  a  procedural  data  type,  this  should  reflect  the  procedure  that  is  exported  from  the  DLL.  }  
       {  Create  a  new  exception  class  to  reflect  a  failed  DLL  load  }  
       TShowPerSN  =  function  (AHandle:  THandle;  ACaption:  String):  BOOL;  StdCall;  
       EDLLLoadError  =  class(Exception);//同时创建一个出错记录类  
     TMAINCLTR  =  class(TForm)  //这里不变,系统自动生成  
     procedure  TMAINCLTR.ToolButton1Click(Sender:  TObject);  
     var    //按钮的调用事件:调用过程  
       LibHandle:  THandle;      ShowPerSN:  TShowPerSN;  
     begin  
       Application.Title:='Title';  
       LibHandle  :=  LoadLibrary('MGRPERSN.DLL');  {  Attempt  to  load  the  DLL  尝试装入DLL文件}  
       try  
           if  LibHandle  =  0  then  
               raise  EDLLLoadError.Create('Unable  to  Load  DLL(无法成功装入MGRPERSN.DLL)');  
           @ShowPerSN  :=  GetProcAddress(LibHandle,  'ShowPerSN');  
           if  not  (@ShowPerSN  =  nil)    then    ShowPerSN(Application.Handle,  'Title')//呼叫出窗体  
           else          RaiseLastWin32Error;  
       finally  
           FreeLibrary(LibHandle);  //  Unload  the  DLL.  
       end;  
     end; 
      

  2.   

    这有什么想不明白的?
    初始化不成功,说明dll内部的部分变量未赋值或函数调用不成功或硬件设备未打开等等。在接下来调用其他dll中的函数时,对这个要做判断。
    比如:dll中有个变量AVar,在初始化的时候,读取某个报表格式,如果读取成功,则变量赋值为1,否则赋值为0.由于报表格式错误,导致这个AVar=0。在dll中有个函数readvar,调用这个函数的时候,先清除文本框中的所有数据,然后判断AVar是否为1,如果是1读取数据,如果不是1,退出函数。
    这样,就是你看到的结果了。
      

  3.   

    初始化都是成功的,我调试过,返回的值确实表示初始化成功,调用函数返回的值也是没问题,dll本身自带的框也会显示出来,但是框上的信息却没有同步显示出来。
    目前怀疑是线程的问题,应该这个dll并不是往本地注册的。求思路。。