我试图在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';
Run Code Online (Sandbox Code Playgroud)
一旦我在我的程序中调用它,我得到AV,我用谷歌搜索如何在Delphi中调用此函数,我发现lpStartupInfo并且lpProcessInfo必须定义如下
var lpStartupInfo: TStartupInfo;
var lpProcessInfo: TProcessInformation
Run Code Online (Sandbox Code Playgroud)
这些功能按预期工作.
我的问题:如果在调用上述外部WinAPI函数时函数参数必须是可变的,我现在怎么办?因为我没有在文档中找到有关此信息的信息.
你的第一次尝试是接近但略有错误.正确的声明应该是这样的:
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';
Run Code Online (Sandbox Code Playgroud)
请注意,最后两个参数是指针(LP表示Win32 API中的指针),因此您将声明非指针变量,然后使用@运算符将其内存地址传递给参数:
var
StartupInfo: TStartupInfoW;
ProcessInfo: TProcessInformation;
begin
CreateProcessWithLogonW(..., @StartupInfo, @ProcessInfo);
end;
Run Code Online (Sandbox Code Playgroud)
但是,参数都是必需的,不能为零.在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;
Run Code Online (Sandbox Code Playgroud)
不过这只是一种便利.无论变量是通过指针还是通过引用传递,相同的内存地址仍然以任何方式传递给API.
1:Embarcadero有一个坏习惯,就是在Win32 API声明(而不是or )中声明可选的指针参数(可以是nil ).这使得用户在需要时更难实际传递nil指针(尽管仍然可以使用笨拙的类型转换来完成).var <type>P<type>^<type>