Delphi定义了外部WinAPI函数的类型

时间:2016-05-26 20:15:43

标签: delphi winapi

我试图在delphi中调用CreateProcessWithLogonW函数

我的第一次尝试如下:

function CreateProcessWithLogonW(
  lpUsername,
  lpDomain,
  lpPassword: LPCWSTR;
  dwLogonFlags: DWORD;
  lpApplicationName: LPCWSTR;
  lpCommandLine: LPWSTR;
  dwCreationFlags: DWORD;
  lpEnvironment: Pointer;
  lpCurrentDirectory: LPCWSTR;
  lpStartupInfo: TStartupInfo;
  lpProcessInfo: TProcessInformation
  ): BOOL;
    stdcall; external 'Advapi32.dll';

一旦我在我的程序中调用它,我得到了AV googled如何在Delphi中调用此函数,我发现lpStartupInfolpProcessInfo必须定义如下

 var lpStartupInfo: TStartupInfo;
 var lpProcessInfo: TProcessInformation

这些功能按预期工作。

我的问题:如果在调用上述外部WinAPI函数时函数参数必须是可变的,我现在怎么办?因为我没有在文档中找到有关此信息的信息。

1 个答案:

答案 0 :(得分:7)

你的第一次尝试很接近但有些错误。正确的声明应该是这样的:

function CreateProcessWithLogonW(
  lpUsername,
  lpDomain,
  lpPassword: LPCWSTR;
  dwLogonFlags: DWORD;
  lpApplicationName: LPCWSTR;
  lpCommandLine: LPWSTR;
  dwCreationFlags: DWORD;
  lpEnvironment: Pointer;
  lpCurrentDirectory: LPCWSTR;
  lpStartupInfo: PStartupInfoW;
  lpProcessInfo: PProcessInformation
  ): BOOL;
    stdcall; external 'Advapi32.dll';

请注意,最后两个参数是指针(LP表示Win32 API中的指针),因此您将声明非指针变量,然后使用@运算符将其内存地址传递给参数:

var
  StartupInfo: TStartupInfoW;
  ProcessInfo: TProcessInformation;
begin
  CreateProcessWithLogonW(..., @StartupInfo, @ProcessInfo);
end;

但是,参数都是必需的,不能为零。在Delphi中,习惯 1 将声明所需的指针参数改为非指针var参数:

function CreateProcessWithLogonW(
  lpUsername,
  lpDomain,
  lpPassword: LPCWSTR;
  dwLogonFlags: DWORD;
  lpApplicationName: LPCWSTR;
  lpCommandLine: LPWSTR;
  dwCreationFlags: DWORD;
  lpEnvironment: Pointer;
  lpCurrentDirectory: LPCWSTR;
  var lpStartupInfo: TStartupInfoW;
  var lpProcessInfo: TProcessInformation
  ): BOOL;
    stdcall; external 'Advapi32.dll';

...

var
  StartupInfo: TStartupInfoW;
  ProcessInfo: TProcessInformation;
begin
  CreateProcessWithLogonW(..., StartupInfo, ProcessInfo);
end;

但这只是一种便利。无论变量是通过 by-pointer 还是 by-reference 传递,相同的内存地址仍然会以任何方式传递给API。

1 :Embarcadero习惯于将可选指针参数( )指定为var <type> in P<type>他们的Win32 API声明(而不是^<type>dict)。这使得用户更难以在他们想要的时候实际传递nil指针(尽管it can still be done,使用笨拙的类型转换)。