我正在尝试调用IsNativeVhdBoot函数,但我收到错误消息参数不正确。
function IsNativeVhdBoot(var NativeVhdBoot:PBOOL):BOOL; external Kernel32 name 'IsNativeVhdBoot';
function _IsNativeVhdBoot:Boolean;
var
pB:PBOOL;
begin
Result := False;
if IsNativeVhdBoot(pB) then
Result := pB^
else RaiseLastOSError;
end;
我也尝试过这样称呼
function __IsNativeVhdBoot: Boolean;
type
TIsNativeVhdBoot = function(
var NativeVhdBoot: pBOOL
): BOOL; stdcall;
var
bNativeVhdBoot: pBOOL;
NativeVhdBoot : TIsNativeVhdBoot;
begin
Result := False;
NativeVhdBoot := GetProcAddress(GetModuleHandle(kernel32), 'IsNativeVhdBoot');
if (@NativeVhdBoot <> nil) then
begin
if not NativeVhdBoot(bNativeVhdBoot) then
RaiseLastOSError;
Result := bNativeVhdBoot^;
end
else
RaiseLastOSError;
end;
我的问题是
- 我调用上述函数时做错了什么。
- 调用时
extranl WinAPI在delphi中调用它有什么区别
function Foo():BOOL; external Kernel32 name 'Foo';
和type TFoo = function(): BOOL; stdcall;
因为我通常会像第一种方法一样进行调用,但是当我收到上述错误消息时,我搜索了如何调用外部函数,并找到了另一种方法。
更新
在 C++ 中测试相同的函数,我得到了相同的错误,我的代码如下
#include "stdafx.h"
#include "Windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
BOOL Result = false;
SetLastError(0);
if (IsNativeVhdBoot(&Result)) {
if (Result) {
printf_s("Running inside VHD\n");
}
else
printf_s("Running inside physical disk drive\n");
}
else
printf("IsNativeVhdBoot failed with error %d.\n", GetLastError());
return 0;
}
最佳答案
在您的第一次尝试中,您的调用约定不匹配,您链接的文档将其声明为“stdcall”。然而,从对问题的评论和这个答案来看,这似乎不是您收到“参数不正确”错误的原因。该调用似乎在所有情况下都会设置此错误。
在这两次尝试中,您的参数都有一个额外的间接级别。文档指出 API 需要 BOOL 变量的地址。该参数的解释实际上与文档中的声明不一致,文档中的声明建议是指向 BOOL 的指针。然而,“winbase.h”中的实际声明与文档中的声明不同,并且符合以下措辞:
WINBASEAPI
BOOL
WINAPI
IsNativeVhdBoot (
_Out_ PBOOL NativeVhdBoot
);
所以参数是“var BOOL”或“PBOOL”,而不是“var PBOOL”。如果您使用“PBOOL”,则必须传递现有的 BOOL 变量的地址,而不是像第一个代码片段中那样指向任何地方的指针。
此时应该注意,这实际上并不重要,因为 API 似乎没有设置“out”参数。这可能在某种程度上是预料之中的,因为文档令人困惑,因为它指出结果将设置为参数,并将作为函数结果返回。这是不寻常的......
请注意,根据文档,函数的返回值并不表明函数失败或成功。这本身是不一致的,因为文档还建议调用 GetLastError
,通常 GetLastError
仅在函数失败时调用,这里我们无法知道它是否失败在调用它之前。无论如何,这意味着您必须删除在错误返回时引发异常的语句。
对于第二个问题,您的第一个声明静态加载库,第二个代码段动态加载库。欲了解更多信息,请参阅documentation 。如上所述,您还有一个额外的区别,即第一个具有寄存器调用约定,但这种区别并不意味着如此。
关于c++ - delphi - 调用外部WinAPI函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36378993/