TBitmap32作为DLL中的函数参数

问题描述 投票:0回答:3

我想使用某些功能创建一个DLL,以便更轻松地管理代码,更新程序等。我不希望任何其他编程语言使用我的DLL,而只是使用Delphi。

因此,在这种情况下,可以安全地将字符串和对象作为参数传递吗?像这样:

function LoadImage(Filename: AnsiString; Bmp32: TBitmap32): Integer;
begin
//
end;

这样的DLL是否可以在不同版本的Delphi中正常工作?

delphi dll
3个回答
0
投票

这样的DLL是否可以在不同版本的Delphi中正常工作?

否,对于字符串和类。

对于字符串,如果使用共享内存管理器,则可以使用,并且Delphi版本具有相同的字符串实现。这不是经常更改的事情,因此您经常可以摆脱它。而且,您通常可以根据参数的传递方式(常量,按值,var等)以及被调用者对其进行的处理来避免使用它。

让我们现在来看课。该类的布局可以在不同版本的Delphi之间变化,并且更可能在不同版本的graphics32之间变化。

即使不是这种情况,也不安全。原因是您有两个RTL / VCL实例。一个在主机可执行文件中,一个在DLL中。当主机可执行文件创建一个实例时,该实例将与主机可执行文件中的RTL / VCL实例一起使用。但是,当您将其传递给DLL并调用非虚拟方法时,执行的代码就是DLL中的代码,该代码需要DLL的RTL / VCL实例。

旨在解决此问题的软件包。使用运行时程序包,并允许所有模块共享同一RTL / VCL实例。

当然,软件包会强制所有各方使用相同的Delphi版本。您可能不想要那样。在这种情况下,剩下的选择就是使用接口公开功能。


0
投票

将对象传递给DLL是混乱的(脆弱,不可取)。如此之多,以至于我不久前就放弃了。现在,如果我想将对象传递给DLL,则可以通过接口来实现。

如果您打算继续走这条路,那么您需要了解几件事。

首先,它很可能(肯定是?)不适用于不同版本的Delphi。

如果您没有使用完全相同的编译选项来构建EXE和DLL,则可能无法正常工作。

如果使用完全相同的编译选项进行编译,它可能仍然无法正常工作。

如果您不使用运行时程序包构建EXE和DLL,则可能会发生奇怪的事情,例如

function Sample(AStrings : TStringList) : Boolean;
var vStrings : TStringList;
begin
  vStrings := TStringList.Create;
  try
    AStrings.Assign(vStrings); //ERROR : Cannot assign a TStringList to a TStringList
  finally
    vStrings.Free;
  end;
end;

这是因为DLL和EXE没有相同的类引用。它们都有自己的TStringList定义,并且不兼容。

因此,根据函数的功能,您可能需要在运行时包中包含TBitmap32。并且根据TBitmap32的功能,您还需要拥有一个运行时包,其中包含直接或间接使用它的每个类。

可能还有更多……我很久以前就停止研究那个雷区。


0
投票

如果您将ShareMem包含在uses部分作为第一个条目,则AnsiStrings应该可以正常工作(在每个新的DLL项目的开头都有关于此主题的大注释!请仔细阅读。)

关于使用对象作为DLL函数/过程的参数的问题:这种方法并不安全,因为您无法确定主机应用程序和DLL中所用类的版本是否相同!

[Rudy Velthius撰写了一篇有关DLL的很好的文章,以获取更多详细信息here

© www.soinside.com 2019 - 2024. All rights reserved.