Delphi-从DLL修改变量
我想制作一个简单的程序,将Edit1.Text设置为“6”(例如,但使用DLL-这很重要)。代码如下: 单位: 和DLL文件:Delphi-从DLL修改变量,delphi,delphi-xe,Delphi,Delphi Xe,我想制作一个简单的程序,将Edit1.Text设置为“6”(例如,但使用DLL-这很重要)。代码如下: 单位: 和DLL文件: library lib; uses Winapi.Windows, System.SysUtils; var a:integer; procedure test; begin a:=6; end; exports test; {$R *.res} begin end. 问题是Edit1.Text仍然是0。你能帮我吗?你有两个不同的变量,一个在DLL中,一个
library lib;
uses
Winapi.Windows, System.SysUtils;
var
a:integer;
procedure test;
begin
a:=6;
end;
exports
test;
{$R *.res}
begin
end.
问题是Edit1.Text仍然是0。你能帮我吗?你有两个不同的变量,一个在DLL中,一个在可执行文件中。它们都被命名为
a
,这是偶然的。设置一个对另一个没有影响
使DLL导出为返回以下值的函数:
function GetValue: Integer; stdcall;
begin
Result := 6;
end;
按如下方式导入:
function GetValue: Integer; stdcall; external dllname;
Edit1.Text := IntToStr(GetValue);
这样称呼它:
function GetValue: Integer; stdcall; external dllname;
Edit1.Text := IntToStr(GetValue);
毫无疑问,真正的代码将不仅仅返回值
6
,但这不是问题。你可以退回任何你喜欢的东西。它们的关键点是使用函数返回值将值从DLL传递给主机 在原始代码的基础上,再添加几个按钮,下面演示如何使用过程(或函数,如果您愿意),并让它们与DLL配合使用
请注意,name
选项不是必需的,除非您希望更改函数的名称或使用重载-因此我已将其注释掉
implementation
procedure test(var a : integer); external 'lib.dll' {name 'test'};
procedure test2(ptr_a : pinteger); external 'lib.dll';
procedure test3(ptr_a : pinteger); external 'lib.dll';
procedure test4(ptr_a : pinteger = nil); external 'lib.dll';
{$R *.dfm}
procedure TForm14.Button1Click(Sender: TObject);
begin
test(a);
Edit1.Text:=Inttostr(a);
end;
procedure TForm14.Button2Click(Sender: TObject);
begin
test2(@a);
Edit1.Text:=Inttostr(a);
end;
procedure TForm14.Button3Click(Sender: TObject);
begin
test3(@a);
Edit1.Text:=Inttostr(a);
end;
procedure TForm14.Button4Click(Sender: TObject);
begin
test4(@a);
test4;
Edit1.Text:=Inttostr(a);
end;
end.
。。。和图书馆机构
var
local_a:integer;
local_Ptr_a:pinteger;
procedure test(var a : integer);
begin
a:=6;
end;
procedure test2(ptr_a : pinteger);
begin
inc(ptr_a^);
end;
procedure test3(ptr_a : pinteger);
begin
inc(local_a);
ptr_a^:=local_a;
end;
procedure test4(ptr_a : pinteger = nil);
begin
if ptr_a = nil then
inc(local_ptr_a^)
else
local_ptr_a := ptr_a;
end;
exports test;
exports test2;
exports test3;
exports test4;
{$R *.res}
begin
local_a := 4;
end.
所以,有一点解释
第一个测试:使用var参数从过程返回值。没问题
第二个测试:将接收变量的地址作为指针传递。我在这里加了一点卷曲,增加了娱乐的价值,呃,价值
第三个测试:显示如何使用DLL所拥有的local值。通过在末尾指定4
来初始化局部值。该过程本身使用与第二个测试相同的机制将值从DLL的局部变量返回到主例程的变量
请注意,test3
分配给程序的变量(1+存储在DLL内存中的值),因此按下按钮3将实际更改a
;因此,按下按钮1-2-2-3-2将使用最后一次更改的值3,而不是先前的值2
最后的测试:在这里我们可以更聪明一点。它使用可选参数机制来改变详细操作
首先,使用一个参数执行过程,该参数是相应类型变量的地址(或指向该变量的指针)。该过程将该地址存储在DLL的内存区域中
接下来,您可以使用no参数执行该过程,它将递增存储指针指向的整数。纯粹为了方便起见,我在每次按下按钮时都会建立变量的地址,但一旦存储了地址,不管该地址是在几微秒前还是一周前设置的,test4
将递增该地址处的整数值-无论它是什么。使用test4(@b)设置地址代码>然后test4
将递增b
——以在使用参数执行过程时最后指向的整数为准
执行test4代码>如果之前某个时候没有执行测试4(@something)
,或者某个内容现在超出范围(比如过程中的局部变量),很可能会导致访问冲突。效果良好:
在主机中
implementation
procedure Test(Edit1: TEdit); stdcall; external 'dll_proj.dll';
动态链接库
exports Test;
Procedure Test(Object1: TEdit); stdcall;
var i:integer;
begin
for i:= 0 to 100 do
begin
Object1.Text:= IntToStr(i);
Application.Processmessages();
Sleep(100);
end;
end;
如果需要在.exe和.dll之间共享变量,标准解决方案是使用内存映射文件。@user24我不这么认为。映射用于跨进程内存共享。这是in-proc。如果启动两个.exe副本并加载相同的.dll,则会跨进程运行。但我相信你不会同意:)@user24不。这是两个过程。但是我没有看到问题中的交叉过程。投票被否决,因为提议的解决方案类似于C,有点危险。OP:IOW,因为DLL通常是用C编写的,所以添加cdecl是常规做法代码>到程序头程序测试(变量a:整数);cdecl;[外部文件名]
告诉Delphi应该使用C调用约定,而不是Delphi的。Delphi很高兴提供可执行文件的约定与DLL的约定相匹配,但很少有聪明的C程序员能够接受这个概念。因为我从来没有在愤怒中用C写过(只是作为一个学术练习),并且在二十年中几乎完全使用Delphi,所以在我自己的代码中,它是第二天性和自动的。