LaK*_*ven 5 delphi dll record shared-memory runtime-packages
是否可以(不使用运行时包或共享内存DLL)在主机应用程序和DLL模块之间传递Record类型,其中Record类型包含函数/过程(Delphi 2006及更高版本)?
让我们假设为了简单起见我们的Record类型不包含任何String字段(因为这当然需要Sharemem DLL),这里是一个例子:
TMyRecord = record
Field1: Integer;
Field2: Double;
function DoSomething(AValue1: Integer; AValue2: Double): Boolean;
end;
Run Code Online (Sandbox Code Playgroud)
因此,简单地说明一下:我可以在主机应用程序和DLL(在任一方向)之间传递TMyRecord的"实例",而无需使用运行时包或共享内存DLL,并从主机EXE执行DoSomething功能和DLL?
我不会建议,无论它是否有效.如果你需要DLL来操作TMyRecord
实例,最安全的选择是让DLL导出普通函数,例如:
DLL:
type
TMyRecord = record
Field1: Integer;
Field2: Double;
end;
function DoSomething(var ARec: TMyRecord; AValue1: Integer; AValue2: Double): Boolean; stdcall;
begin
...
end;
exports
DoSomething;
end.
Run Code Online (Sandbox Code Playgroud)
应用程序:
type
TMyRecord = record
Field1: Integer;
Field2: Double;
end;
function DoSomething(var ARec: TMyRecord; AValue1: Integer; AValue2: Double): Boolean; stdcall; external 'My.dll';
procedure DoSomethingInDll;
var
Rec: TMyRecord;
//...
begin
//...
if DoSomething(Rec, 123, 123.45) then
begin
//...
end else
begin
//...
end;
//...
end;
Run Code Online (Sandbox Code Playgroud)
小智 4
如果我正确理解你的问题,那么你就可以做到,这是一种方法:
测试DLL
library TestDll;
uses
SysUtils,
Classes,
uCommon in 'uCommon.pas';
{$R *.res}
procedure TakeMyFancyRecord(AMyFancyRecord: PMyFancyRecord); stdcall;
begin
AMyFancyRecord^.DoSomething;
end;
exports
TakeMyFancyRecord name 'TakeMyFancyRecord';
begin
end.
Run Code Online (Sandbox Code Playgroud)
uCommon.pas <- 由应用程序和 dll 使用,定义您喜欢的记录的单元
unit uCommon;
interface
type
PMyFancyRecord = ^TMyFancyRecord;
TMyFancyRecord = record
Field1: Integer;
Field2: Double;
procedure DoSomething;
end;
implementation
uses
Dialogs;
{ TMyFancyRecord }
procedure TMyFancyRecord.DoSomething;
begin
ShowMessageFmt( 'Field1: %d'#$D#$A'Field2: %f', [ Field1, Field2 ] );
end;
end.
Run Code Online (Sandbox Code Playgroud)
最后是一个测试应用程序,文件 - >新建 - > vcl表单应用程序,在表单上放置一个按钮,在uses子句中包含uCommon.pas,添加对外部方法的引用
procedure TakeMyFancyRecord(AMyFancyRecord: PMyFancyRecord); stdcall;
external 'testdll.dll' name 'TakeMyFancyRecord';
Run Code Online (Sandbox Code Playgroud)
并在按钮的单击事件中添加
procedure TForm1.Button1Click(Sender: TObject);
var
LMyFancyRecord: TMyFancyRecord;
begin
LMyFancyRecord.Field1 := 2012;
LMyFancyRecord.Field2 := Pi;
TakeMyFancyRecord( @LMyFancyRecord );
end;
Run Code Online (Sandbox Code Playgroud)
免责声明:
享受!
大卫·赫弗南编辑
百分百明确的是,执行的 DoSomething 方法是 DLL 中定义的方法。EXE 中定义的 DoSomething 方法永远不会在此代码中执行。
归档时间: |
|
查看次数: |
1341 次 |
最近记录: |