如何从Delphi调用DLL函数?

时间:2014-05-29 16:07:37

标签: delphi dll

// Get a list of accounts in a domain separated by \x00 and ended by \x00\x00
Function GetUserList(AName: PAnsiChar; Var List; Size: Longint): Longint; StdCall;

我需要从XE6调用上述内容。

有人能够发表一个我能做的例子 获取此缓冲区,并将其放入流或字符串。

变量" List"我应该读一些缓冲区 关闭用户列表。

在尝试了几个选项之后,我尝试了所有选项,例如:

谢谢!

var
  Buffer: array of Byte;
  iCount : Integer;
  sName : AnsiString;
begin
  ...
  SetLength(Buffer, 4096);
  iCount := GetUserListTest(PAnsiChar(sName)@Buffer[0], Length(Buffer)); // cannot
  // iCount := GetUserList(PAnsiChar(sName), Buffer, Length(Buffer));

1 个答案:

答案 0 :(得分:2)

这不是Win32 API函数,因此它必须是第三方函数。向供应商询问一个例子。

var参数要求您将变量传递给它。 var接收变量的地址。 @Buffer[0]不满足该要求,因为@返回一个指针,然后var以指针本身的地址结束,而不是指向的变量的地址。该函数期望指向缓冲区的指针。通过使用var接收该指针,您需要删除@并传递第一个数组元素,以便该元素的地址(实际上是缓冲区的地址)将传递给功能,例如:

iCount := GetUserList(PAnsiChar(sName), Buffer[0], iCount);

或者,您可以使用此语法,它将传递第一个元素的相同地址:

iCount := GetUserList(PAnsiChar(sName), PByte(Buffer)^, iCount);

现在,有了这个说法,很可能函数可以允许你查询它所需的数组大小,这样你就可以只分配实际需要的东西(但是检查文档是否确定,我在这里做了一个假设,因为你没有另外说过)),例如:

procedure GetDomainUsers(const Domain: AnsiString; Users: TStrings);
var
  Buffer: array of AnsiChar;
  iCount : Integer;
  User: PAnsiChar;
begin
  // this call ASSUMES the function returns the needed
  // bytecount when given a NULL/empty array - check
  // the documentation!!!
  iCount := GetUserList(PAnsiChar(Domain), PAnsiChar(nil)^, 0);
  if iCount > 0 then
  begin
    SetLength(Buffer, iCount);
    iCount := GetUserList(PAnsiChar(Domain), Buffer[0]{or: PAnsiChar(Buffer)^}, iCount);
  end;
  if iCount > 0 then
  begin
    Users.BeginUpdate;
    try
      User := PAnsiChar(Buffer);
      while User^ <> #0 do
      begin
        Users.Add(User);
        Inc(User, StrLen(User)+1);
      end;
    finally
      Users.EndUpdate;
    end;
  end;
end;

如果这不起作用,那么你必须预先分配一个大数组:

procedure GetDomainUsers(const Domain: AnsiString; Users: TStrings);
var
  Buffer: array of AnsiChar;
  User: PAnsiChar;
begin
  SetLength(Buffer, 1024);
  if GetUserList(PAnsiChar(Domain), Buffer[0]{or: PAnsiChar(Buffer)^}, Length(Buffer)) > 0 then
  begin
    Users.BeginUpdate;
    try
      User := PAnsiChar(Buffer);
      while User^ <> #0 do
      begin
        Users.Add(User);
        Inc(User, StrLen(User)+1);
      end;
    finally
      Users.EndUpdate;
    end;
  end;
end;