delphi - Delphi中的AccessViolationException-不可能(检查一下,令人难以置信……)

标签 delphi error-handling access-violation

德尔福XE。 Windows 7的。

有一个函数(请参见下面的代码)或I:=0在大项目中导致AV错误。在新项目中,相同功能没有错误!!!我删除了大项目中的所有内容,只剩下一个按钮和那个功能。仍然会导致错误...

出现错误的行:

if ISAeroEnabled then // this line is a cause
       i:=0;         // or this line

我到处都设置了断点(我检查了整个功能,在上设置了断点EACH LINE ->函数中没有错误),调试器向我显示错误在i:=0;

如果要删除功能(并保留i:=0;)-> 一切正常!

错误消息:First chance exception at $747FB727. Exception class EAccessViolation with message 'Access violation at address 004AE5AF in module 'MngProject.exe'. Write of address 0017FFF8'. Process MngProject.exe (4980)
为什么它在新项目中有效,但在我的项目中无效?

这是整个项目:http://www.2shared.com/file/UP22Om4j/Bug.html

编码:
unit MainFormModule;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  StdCtrls;
type
  TMainForm = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public

    { Public declarations }
  end;

var
     mainform:tmainform;
implementation
{$R *.dfm}

function  ISAeroEnabled: Boolean;
type
  _DwmIsCompositionEnabledFunc = function(IsEnabled: PBoolean): HRESULT; stdcall;
var
  Flag                       : Boolean;
  DllHandle                  : THandle;
  OsVersion                  : TOSVersionInfo;
  DwmIsCompositionEnabledFunc: _DwmIsCompositionEnabledFunc;
begin
  Result:=False;
  ZeroMemory(@OsVersion, SizeOf(OsVersion));
  OsVersion.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);

  if ((GetVersionEx(OsVersion)) and (OsVersion.dwPlatformId = VER_PLATFORM_WIN32_NT) and (OsVersion.dwMajorVersion >= 6)) then //is Vista or Win7?
  begin
    DllHandle := LoadLibrary('dwmapi.dll');
    if DllHandle <> 0 then
    begin
      @DwmIsCompositionEnabledFunc := GetProcAddress(DllHandle, 'DwmIsCompositionEnabled');
      if (@DwmIsCompositionEnabledFunc <> nil) then
      begin
        DwmIsCompositionEnabledFunc(@Flag);
        Result:=Flag;
      end;
    end;
      FreeLibrary(DllHandle);
  end;
end;

procedure Tmainform.Button1Click(Sender: TObject);
var i:integer;
begin
    if ISAeroEnabled then // AV is here
       i:=0;              // Or here
end;
end.

最佳答案

尝试将PBoolean更改为PBOOL

function(IsEnabled: PBOOL): HRESULT; stdcall;

var
  Flag: BOOL;

PBoolean是指向1字节大小的Pascal bool(boolean) 值的指针。 PBOOL是指向Windows(基于C)BOOL的指针,其大小为4个字节。您需要匹配Windows预期的大小。

通常,将Windows API调用转换为Delphi时,请使用与API相同的命名数据类型。 Windows.pas具有将这些定义映射到Delphi类型的类型定义,例如type BOOL = LongBool;
同样,在Delphi中通常(但不是必需)将指针参数更改为var。 var参数是用于按引用传递的Pascal语法糖,在C中不可用。
function(var IsEnabled: BOOL): HRESULT; stdcall;
....
    DwmIsCompositionEnabledFunc(Flag); // no @ operator

注意:我无法测试,因为我只有XP。

关于delphi - Delphi中的AccessViolationException-不可能(检查一下,令人难以置信……),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7198646/

相关文章:

error-handling - 如何使用自定义结构实现错误

ruby - Controller#index中的NameError未初始化的常量

forms - Delphi - 如何从该表单上的 TFrame 内关闭表单?

delphi - Delphi 是否提供用于表单创建通知的事件处理程序?

java - 一段奇怪的德尔福代码

c#-4.0 - Windows Service中的错误处理

windows - 如何显示带有选定文件的资源管理器?

c++ - 初始化一个复杂的对象。当我不这样做时出错?

C++宏导致空指针

.net - 确定 System.AccessViolationException 的原因