首先,这个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里的方法,得到的结果却是界面跟数据都有。想了很久,搞不明白,求神人指教,或者给思路,谢谢。好的答案思路追分。
其次,我有一个解决方案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
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;
初始化不成功,说明dll内部的部分变量未赋值或函数调用不成功或硬件设备未打开等等。在接下来调用其他dll中的函数时,对这个要做判断。
比如:dll中有个变量AVar,在初始化的时候,读取某个报表格式,如果读取成功,则变量赋值为1,否则赋值为0.由于报表格式错误,导致这个AVar=0。在dll中有个函数readvar,调用这个函数的时候,先清除文本框中的所有数据,然后判断AVar是否为1,如果是1读取数据,如果不是1,退出函数。
这样,就是你看到的结果了。
目前怀疑是线程的问题,应该这个dll并不是往本地注册的。求思路。。