Delphi dll 传递字符串

发布时间 2023-10-05 10:05:51作者: Tag
//dll code

uses
//  ShareMem,
  SysUtils,
  Windows,
  Math;

{$R *.res}


function TestString1(Buffer: PChar): PChar; stdcall;
var
 Tmpstr:string;
begin
 try
  Tmpstr := Buffer;
  if Tmpstr <> '' then
  begin
   Result := StrAlloc(Length(Tmpstr)+1);
   StrCopy(Result, Buffer);
  end
  else
   Result := nil;
 finally
  Tmpstr := '';
 end;
end;

function TestString2(Buffer, lpBuffer: PChar;Buflen:integer):Integer; stdcall;
var
 Tmpstr:string;
begin
 try
  Tmpstr := Buffer;
  if Tmpstr <> '' then
  begin
   Result := Min(Buflen, Buflen); //这里做测试,就弄一样的了
   Tmpstr := Copy(Tmpstr, 1, Result);
   StrCopy(lpBuffer,PChar(Tmpstr));
  end
  else
   Result := 0;
 finally
  Tmpstr := '';
 end;
end;


procedure FreeString(Buffer:PChar); stdcall;
begin
 StrDispose(Buffer);
end;


exports
  TestString1,
  TestString2,
  FreeString;

begin
end.

end.

//调用方
type
  TestString1Func = function (Buffer: PChar): PChar; stdcall;
  TestString2Func = function (Buffer, lpBuffer: PChar;Buflen:integer):Integer; stdcall;
  FreeStringProc  = procedure(Buffer:PChar); stdcall;


procedure TForm1.btn5Click(Sender: TObject);

var
  dll: THandle;
  TestString1: TestString1Func;
  FreeString: FreeStringProc;
  p, res: PChar;
begin
  dll :=  LoadLibrary('D:\云端工具\17wpdll\Y7WP_GoodsParser.dll');
  if dll <> 0 then
  begin
    @TestString1 := GetProcAddress(dll, 'TestString1');
    @FreeString := GetProcAddress(dll, 'FreeString');
    if Assigned(TestString1) then
    begin
      res  := TestString1(pchar(mmo1.Text)); // 调用DLL
       // 使用返回的字符串
      ShowMessage(res);

     // 释放内存
      FreeString(res);

      FreeLibrary(dll);
    end;
  end;
end;


procedure TForm1.btn6Click(Sender: TObject);
var
  dll: THandle;
  TestString2: TestString2Func;
  outp: PChar;
  outpsize:Integer;
begin
  dll :=  LoadLibrary('D:\云端工具\17wpdll\Y7WP_GoodsParser.dll');
  if dll <> 0 then
  begin
    @TestString2 := GetProcAddress(dll, 'TestString2');
    if Assigned(TestString2) then
    begin
      outpsize := length(mmo1.Text)+1;
      outp := StrAlloc(outpsize);
      outpsize  := TestString2(pchar(mmo1.Text), outp, outpsize); // 调用DLL
       // 使用返回的字符串
      ShowMessage('长度为:'+IntToStr(outpsize));
      ShowMessage(outp);
      StrDispose(outp);
      FreeLibrary(dll);
    end;
  end;
end;

以上提供两种方式:
1.dll分配内存,跟释放(需要调用方主动调用释放函数)。

2.调用方分配内存,自己释放。(需要知道长度是多少)。不知道的话,可以用两次,这里没有处理。需要判断lpbuffer是否nil

还有一种就是工程文件第一单元引用 ShareMem,调用方也是。
参数跟返回的类型直接用string ,不用管释放。程序发布时要带上 borlndmm.dll

缺陷:只能是 delphi 调用。(同版本,高版本没有试过。高版本的字符串默认不是ansichar了)