Delphi中DLL/Exe中的字符串处理
我继承了一个由EXE和DLL组成的应用程序,两者都使用ShareMem作为第一个单元。应用程序希望传递一个字符串(字符串类型,而不是PChar/PWideChar) 应用程序有一个定义“字符串”变量的单元,该变量包含在EXE和DLL中。我们的期望是DLL将设置变量(基于传递给DLL的一些数据),然后使用它 我试图提供一个最小的完整示例应用程序,演示以下行为 在共享单元中定义的变量Delphi中DLL/Exe中的字符串处理,delphi,dll,Delphi,Dll,我继承了一个由EXE和DLL组成的应用程序,两者都使用ShareMem作为第一个单元。应用程序希望传递一个字符串(字符串类型,而不是PChar/PWideChar) 应用程序有一个定义“字符串”变量的单元,该变量包含在EXE和DLL中。我们的期望是DLL将设置变量(基于传递给DLL的一些数据),然后使用它 我试图提供一个最小的完整示例应用程序,演示以下行为 在共享单元中定义的变量 unit SharedValues; interface var SomeVariable: string;
unit SharedValues;
interface
var
SomeVariable: string;
implementation
end.
执行。。。
朝鲜民主主义人民共和国。。。
方案和项目
uses
ShareMem,
Vcl.Forms,
Main in 'src\Main.pas' {Form1},
SharedValues in '..\Shared\SharedValues.pas';
主要形式
procedure TForm1.Button1Click(Sender: TObject);
const
lLibraryName = 'DllProject.dll';
var
lDllHandle: THandle;
lLength: Integer;
lCreatorFunc: function: Integer; stdcall;
begin
SharedValues.SomeVariable := 'Shared variable set in EXE';
lDllHandle := LoadLibrary(PChar(lLibraryName));
if (lDllHandle <> 0) then
begin
lCreatorFunc := GetProcAddress(lDllHandle, 'LoadDll');
if Assigned(lCreatorFunc) then
begin
OutputDebugString(PChar(Format('In Exe (before dll): Shared Variable: %s (%d) 0x%p', [SharedValues.SomeVariable, Length(SharedValues.SomeVariable), @SharedValues.SomeVariable])));
lLength := lCreatorFunc;
OutputDebugString(PChar(Format('Length returned from DLL: %d', [lLength])));
OutputDebugString(PChar(Format('In Exe (after dll): Shared Variable: %s (%d) 0x%p', [SharedValues.SomeVariable, Length(SharedValues.SomeVariable), @SharedValues.SomeVariable])));
end;
end else begin
ShowMessage(SysErrorMessage(GetLastError));
end;
end;
以上的输出
Exe Before: Shared variable set in EXE
DLL Before:
DLL After: short
Exe After: Shared variable set in EXE Length: 5
这是怎么回事?当我调试并查看变量的内存位置时(使用Addr和/或“@”),看起来变量在exe和dll中的地址相同,但我认为我在exe中得到了变量的副本,在dll中得到了副本。。。但是,在调试器下,我看到设置“SharedValues.SomeVariable”后,变量保持不变(即,似乎是来自exe的值,而不是来自DLL中设置的值)
有人能在这里澄清一下/给我指出正确的方向吗?当然,它们是不同的变量,Sharemem可以用来向exe/dll传递字符串或从exe/dll传递字符串。只需在LoadDll中输出地址。您看到没有设置变量的图片了吗?在实际应用程序中,该变量似乎是一个空字符串,后来由于该字符串为空而失败,尽管在DLL中设置了该字符串。调试器可能会被类似命名的变量混淆。调试输出地址、内容等。这是不可能的。重复测试。当您使用sharemem时,共享的是内存管理器,dll中的变量(指针)仍然存在于从加载地址开始的模块的内存映像中,您可以看到按ctrl+alt+M。
Exe Before: Shared variable set in EXE
DLL Before:
DLL After: short
Exe After: Shared variable set in EXE Length: 5