gpt4 book ai didi

delphi - 我第一次调用 DLL

转载 作者:行者123 更新时间:2023-12-03 18:18:45 25 4
gpt4 key购买 nike

我快疯了。

我是初学者,我想制作我的第一个 DLL。我遵循了本指南:

http://www.tutorialspoint.com/dll/dll_delphi_example.htm

我想设置有关程序版本的文本信息并在需要时读取它,因此通过主应用程序将其显示给用户。这只是一个例子,以保持对 DLL 的信心,我已经知道还有很多其他方法可以实现这一点。

现在我正尝试从这样的 DLL 中读取变量“versione”:

library Clientdll;


uses SysUtils, Classes, Dialogs;

{$R *.res}


function Versione(var messaggio, versione: String):string; export; stdcall;
begin
versione:='Nessun dato ricavato. Valore di chiamata alla DLL errato!';
if messaggio='chiama' then versione:='v4.0.0 build 31';
end;

exports versione;

begin
end.

在主应用程序中,我这样写:

[...]

implementation

uses unit2;

{$R *.dfm}
function Versione(var messaggio, versione:string):string; stdcall; external 'Clientdll.dll'

[...]

现在我说'好吧,我只需调用 DLL,仅此而已......'。所以:

procedure TForm1.Button1Click(Sender: TObject);
var x, y:string;
begin
x:='chiama';
Versione(x,y);
showmessage(y);
end;

我可以在对话框中读取 v4.0.0 build 31,但是当我按下 OK 时,我收到了这个错误:

“无效指针操作”。

有什么想法吗?

我试着google了一下,但是我的英语很差,有些答案很难理解,还有翻译工具!

最佳答案

不要使用String 作为参数类型。这在您使用 File->New->Other->Delphi Projects->DLL Wizard 创建新 DLL 时 IDE 生成的注释中有明确解释:

{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. }

此外,使用 Delphi 字符串意味着您的 DLL 函数无法从其他语言(例如 C)调用。

您还应该期望调用应用程序为您提供用于放置结果的内存(以及一个长度参数,告诉您该内存缓冲区有多大)。

这是一个最小(非常无用)的 Delphi dll 示例,它具有一个函数,以及一个调用它的测试应用程序。 (正如我所说,DLL 是毫无意义的。任何实际的 DLL 都应该设计为将功能代码放在它自己的单元中,而不是放在项目文件中。)

示例 DLL 源:

library SimpleTest;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Classes;

{$R *.res}

// Parameters:
// arg: Argument that indicates whether this is a test or
// something else, so we know which value to return
// Buffer: The space in which to place the result
// Len: The length of the buffer provided
function TestDLL(const arg: PChar; const Buffer: PChar;
const Len: Integer): Boolean; stdcall;
begin
// Make sure we use the Len parameter, so we don't overflow
// the memory we were given. StrLCopy will copy a maximum of
// Len characters, even if the length of the string provided
// as the 'source' parameter is longer.
if arg = 'Test' then
StrLCopy(Buffer, 'Test result', Len)
else
StrLCopy(Buffer, 'Non-test result', Len);
Result := True;
end;

exports
TestDll;

begin

end.

调用它的测试应用程序的表单:

unit DLLTestForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form4: TForm4;

implementation

{$R *.dfm}

function TestDLL(const arg: PChar; const Buffer: PChar; const Len: Integer): Boolean; stdcall;
external 'SimpleTest.dll';

procedure TForm4.Button1Click(Sender: TObject);
var
Parm1: String;
Parm2: String;
BuffLen: Integer;
begin
Parm1 := 'Test';
// Length of buffer (including null terminator) for DLL call
// Chosen arbitrarily - I know the DLL won't return more than 15 + the
// null. I'm pretending I don't, though, and allowing extra space. The
// DLL won't return more than 30 characters, even if it has more to say,
// because it uses StrLCopy to limit the result to Len characters.
BuffLen := 30;

// Allocate space for return value
SetLength(Parm2, BuffLen);

// Call the DLL with `Test` arg
if TestDLL(PChar(Parm1), PChar(Parm2), BuffLen) then
ShowMessage(Parm2);

// Call the DLL with a different parameter value
Parm1 := 'Other';
if TestDLL(PChar(Parm1), PChar(Parm2), BuffLen) then
ShowMessage(Parm2);
end;

end.

关于delphi - 我第一次调用 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21800297/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com