使用LoadLibrary()调用DLL,使用FreeLibrary()释放之后出现访问报错

时间:2022-08-09 08:43:57
动态链接库代码如下:
library DLLSplitString;

uses
  SysUtils,
  Classes;

{$R *.res}


//  以下函数实现根据分隔符分隔字符,并将分隔出来的字符写进StringList中。
function SplitString(Source, Deli: string ): TStringList;stdcall;
var
  EndOfCurrentString: byte;
  StringList: TStringList;
begin
  StringList := TStringList.Create;
  while Pos(Deli, Source)>0 do
  begin
    EndOfCurrentString := Pos(Deli, Source);
    StringList.add(Copy(Source, 1, EndOfCurrentString - 1));
    Source := Copy(Source, EndOfCurrentString + length(Deli), length(Source) - EndOfCurrentString);
  end;
  Result := StringList;
  StringList.Add(source);
end;
exports
  SplitString;

  begin
end.

程序中调用:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  OneHandle: THandle;
  SplitString: function (Source, Deli: string): TStringList; stdcall;
  StringList: TStringList;
begin
  StringList := TStringList.Create;
  OneHandle := LoadLibrary('DLLSplitString.dll'); //动态载入DLL,并返回其句柄
  try
    if OneHandle <> 0 then //如果载入成功则获取SplitString函数的地址
      @SplitString := GetProcAddress(OneHandle, 'SplitString');
    if not (@SplitString = nil) then
    begin
      StringList := SplitString('a;b;c;d', ';');
      for i := 0 to StringList.Count - 1 do
        edit1.Text := edit1.Text + StringList[i];
    end
    else
      RaiseLastWin32Error;
  finally
    FreeLibrary(OneHandle); //调用完毕收回DLL占用的资源
  end;
end;

在执行 FreeLibrary(OneHandle); 之句的时候报错内存地址之类的错。在网上查了一下,可能是说在DLL中使用了全局变量。不知如何改进相关的代码以解决这个问题。

5 个解决方案

#1


你的dll没有使用全局变量啊。

不过 建议你的函数返回值 不要用 TStringList 

你可以返回一个数组 或者其他。

#2


在dll和程序工程文件的uses里加上ShareMem。

#3


在dll和程序工程文件的uses里加上ShareMem后还是报同样的错,问题并没有解决。

#4


原来是要把ShareMem加到所有单元的最前边才可以。问题解决了。

#5


现在又出现这样一个问题,在关闭程序的时候,报内存地址方面的错。

#1


你的dll没有使用全局变量啊。

不过 建议你的函数返回值 不要用 TStringList 

你可以返回一个数组 或者其他。

#2


在dll和程序工程文件的uses里加上ShareMem。

#3


在dll和程序工程文件的uses里加上ShareMem后还是报同样的错,问题并没有解决。

#4


原来是要把ShareMem加到所有单元的最前边才可以。问题解决了。

#5


现在又出现这样一个问题,在关闭程序的时候,报内存地址方面的错。