对于我的上一个项目,我在delphi应用程序中使用了很多帧,所以我决定创建dll并将它们放在dll中(所有在Delphi中创建)
我已经浏览了很多网站,并提出了有效的代码,但是对于该示例,我必须使用使用运行时包构建来编译应用程序和dll,这意味着我还需要分发bpls 。如果不检查构建与运行时包错误即将到来
这是我找到的代码
在exe
中procedure TForm1.Button1Click(Sender: TObject);
type
TGetTheFrame =Function( Owner: TComponent; TheParent: TWinControl ): TFrame; stdcall ;
var
GetTheFrame : TGetTheFrame;
begin
try
GetTheFrame(application,TabSheet1).Free ;
except
end;
frm := GetTheFrame(application,TabSheet1) ;
dllHandle := LoadLibrary('project1.dll') ;
if dllHandle <> 0 then
begin
GetTheFrame := GetProcAddress(dllHandle, 'GetTheFrame') ;
frm := GetTheFrame(application,TabSheet1) //call the function
{ ShowMessage('error function not found') ;
FreeLibrary(dllHandle) ; }
end
else
begin
ShowMessage('xxxx.dll not found / not loaded') ;
end
在dll中
Function GetTheFrame( Owner: TComponent; TheParent: TWinControl ): TFrame; stdcall;
Begin
Result := TFrame2.Create( Owner );
Result.Parent := TheParent;
End;
这就是我希望这段代码在没有运行时包的情况下工作
答案 0 :(得分:7)
太糟糕了。没有运行时包,该代码将无法运行。 (使用运行时包,您应该使用LoadPackage
而不是LoadLibrary
。)
没有包,程序的每个模块(EXE和每个DLL)都有自己的所有标准类定义的副本,包括TFrame
,TWinControl
,甚至{{1} }。 EXE中的TObject
类看起来不像DLL的TWinControl
。
由于您在模块之间共享类,因此您需要确保它们都具有相同的类定义,并且运行时包就是您这样做的方式。
如果您真的不使用运行时包,那么您需要更改DLL的接口,以便它不共享任何Delphi对象类型。传递控件的TWinControl
属性或任何其他TWinControl
值作为父窗口,而不是Handle
父级。 DLL代码将无法再假设父级有Delphi对象,并且EXE将无法假设它接收的控件是Delphi对象;他们将被限制使用Windows API来操纵窗口句柄和发送消息。