如何从Delphi调用DLL函数?

如何从Delphi调用DLL函数?,delphi,dll,Delphi,Dll,我需要从XE6打电话给上面的人 有没有人能帮我举个例子 获取此缓冲区,并将其放入流或字符串中 变量“List”应该填充一些缓冲区,我可以读取这些缓冲区 从用户列表中删除 在尝试了几个选项后,我尝试了所有选项,例如: 谢谢 // Get a list of accounts in a domain separated by \x00 and ended by \x00\x00 Function GetUserList(AName: PAnsiChar; Var List; Size: Longin

我需要从XE6打电话给上面的人

有没有人能帮我举个例子 获取此缓冲区,并将其放入流或字符串中

变量“List”应该填充一些缓冲区,我可以读取这些缓冲区 从用户列表中删除

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

谢谢

// 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;

这不是Win32 API函数,因此它必须是第三方函数。请供应商举个例子

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

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));
或者,您可以改为使用此语法,它将传递第一个元素的相同地址:

iCount := GetUserList(PAnsiChar(sName), Buffer[0], iCount);
现在,尽管如此,函数可能允许您查询必要的数组大小,这样您就可以只分配实际需要的内容(但请检查文档以确保,我在这里做一个假设,因为您没有说过其他内容),例如:

procedure-GetDomainUsers(const-Domain:AnsiString;Users:TStrings);
变量
缓冲区:AnsiChar的数组;
i计数:整数;
用户:PAnsiChar;
开始
//此调用假定函数返回所需的
//给定空/空数组时的字节数-检查
//文档!!!
iCount:=GetUserList(PAnsiChar(域),PAnsiChar(nil)^,0);
如果i计数>0,则
开始
SetLength(缓冲区、iCount);
iCount:=GetUserList(PAnsiChar(域),缓冲区[0]{或:PAnsiChar(缓冲区)^},iCount);
结束;
如果i计数>0,则
开始
Users.BeginUpdate;
尝试
用户:=PAnsiChar(缓冲区);
而用户^#0做
开始
用户。添加(用户);
Inc(用户,斯特伦(用户)+1);
结束;
最后
Users.EndUpdate;
结束;
结束;
结束;
如果不起作用,则必须预先分配一个大型阵列:

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);
变量
缓冲区:AnsiChar的数组;
用户:PAnsiChar;
开始
设置长度(缓冲区,1024);
如果GetUserList(PAnsiChar(Domain),Buffer[0]{或:PAnsiChar(Buffer)^},Length(Buffer))>0,那么
开始
Users.BeginUpdate;
尝试
用户:=PAnsiChar(缓冲区);
而用户^#0做
开始
用户。添加(用户);
Inc(用户,斯特伦(用户)+1);
结束;
最后
Users.EndUpdate;
结束;
结束;
结束;

您需要知道该职能部门遵守的合同的确切细节。没有这些知识,你只能猜测。您需要阅读文档以找到我们的。嗨,雷米,非常感谢您提供的代码示例。我意识到确实有一个GetUserCount函数。不支持此API。函数GetUserList现在没有崩溃,尽管字符串还没有填满。我认为这一定与“被\x00分隔并以\x00\x00结尾”有关。我试着用#00或#0#0替换#0,但TStrings似乎仍然没有填满。是否有一种方法可以简单地将数组分配给一个TStrings.Text。返回的数组缓冲区中似乎已经有了分隔符?或者读取返回的数组中的内容的方法?…由于POST中的限制而继续//获取帐户总数函数GetUserCount(aName:PAnsiChar):Longint;StdCall;//获取以\x00分隔并以\x00\x00函数GetUserList结尾的帐户列表(aName:PAnsiChar;Var list;Size:Longint):Longint;StdCall;iUserCount:=GetUserList(PAnsiChar(域),PAnsiChar(nil)^,0);如果iUserCount>0,则开始设置长度(缓冲区,iUserCount)//iCount:=GetUserList(域,缓冲区[0],iCount);iCount:=GetUserList(PAnsiChar(域)、PAnsiChar(缓冲区)^、iUserCount);结束;
GetUserList()
实际返回什么值?它是错误值还是成功值?我假设它返回一个字节计数,但您还没有说
GetUserCount()
无法帮助您知道要为数组分配多少字节。您不能按原样将数组传递给
TStringList
,必须迭代数组,我给您的代码就是这样做的。空终止的双空终止格式在API编程中并不少见。您需要找出数组未填充的原因,很可能是函数失败并出现错误。它返回了-3。我想是-03美元吧?我可以简单地为数组分配足够大的字节,并简单地依靠\x00和\x00\x00知道何时停止吗?如果是这样,你能给我一个代码示例吗?很抱歉打扰你。我试着读了好几个小时,但所有安西卡尔的东西都令人困惑({Function Result Codes}S_OK=$00;E_FAILURE=-$01;E_LICENSE=-$02;E_PARAMS=-$03;E_PATH=-$04;E_CONFIG=-$05;函数失败并出现
E_PARAMS
错误(在哪个调用中-第一个或第二个?我假设是第一个。它可能不喜欢
nil
)。请阅读文档以了解哪些参数是它可以接受的。我无法回答您关于分配大型数组的问题,因为我不知道函数需要什么。请阅读文档。
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;