全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3553
推到 Plurk!
推到 Facebook!

Import DLL與Invalid Pointer Operation Error

尚未結案
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-03-15 14:37:19 IP:218.167.xxx.xxx 未訂閱
以下是我一段程式碼:
procedure TfmMain.GetPwrCabilities;
var
  SystemPowerCap: SYSTEM_POWER_CAPABILITIES;
begin
  try
    try
      if GetPwrCapabilities(SystemPowerCap) then <=得不到true
      begin
        bSupportS1 := SystemPowerCap.bSystemS1;
        bSupportS3 := SystemPowerCap.bSystemS3;
        bSupportS4 := SystemPowerCap.bSystemS4;
      end
      else
        TakeLog('***ERROR in getting System Power Capbilities:'   SysErrorMessage(GetLastError));
    except on E: Exception do
      begin
        MessageDlg(E.Message, mtError, [mbOK], 0);
        TakeLog('***ERROR in getting System Power Capbilities');
      end
    end;      finally      end;
end;    在另一Unit中相關的宣告如下:    type      SYSTEM_POWER_CAPABILITIES = packed record
    bPowerButtonPresent: Boolean;
    bSleepButtonPresent: Boolean;
    bLidPresent: Boolean;
    bSystemS1: Boolean;
    bSystemS2: Boolean;
    bSystemS3: Boolean;
    bSystemS4: Boolean;
    bSystemS5: Boolean;
    bHiberFilePresent: Boolean;
    bFullWake: Boolean;
    bVideoDimPresent: Boolean;
    bApmPresent: Boolean;
    bUpsPresent: Boolean;
    bThermalControl: Boolean;
    bProcessorThrottle: Boolean;
    ProcessorMinThrottle: UCHAR;
    ProcessorMaxThrottle: UCHAR;
    spare2: array[0..3] of UCHAR;
    DiskSpinDown: Boolean;
    spare3: array[0..7] of UCHAR;
    SystemBatteriesPresent: Boolean;
    BatteriesAreShortTerm: Boolean;
    BatteryScale: array[0..2] of BATTERY_REPORTING_SCALE;
    AcOnLineWake: SYSTEM_POWER_STATE;
    SoftLidWake: SYSTEM_POWER_STATE;
    RtcWake: SYSTEM_POWER_STATE;
    MinDeviceWakeState: SYSTEM_POWER_STATE;
    DefaultLowLatencyWake: SYSTEM_POWER_STATE;
  end;
  PSYSTEM_POWER_CAPABILITIES = ^SYSTEM_POWER_CAPABILITIES;
...
...    function GetPwrCapabilities(var SystemPowerCapabilities: SYSTEM_POWER_CAPABILITIES): Boolean; stdcall;
...
...
implementation
...
function GetPwrCapabilities; external powerprof name 'GetPwrCapabilities';
...    我本來想說是不是我import API宣告有問題,改成這樣試試看:
function GetPwrCapabilities(lpSystemPowerCapabilities: PSYSTEM_POWER_CAPABILITIES): Boolean; stdcall;    程式碼改成這樣:
procedure TfmMain.GetPwrCabilities;
var
  SystemPowerCap: PSYSTEM_POWER_CAPABILITIES;
begin
  try
    GetMem(SystemPowerCap, SizeOf(SYSTEM_POWER_CAPABILITIES));
    try
      if GetPwrCapabilities(SystemPowerCap) then <=可以通過了
      begin
        bSupportS1 := SystemPowerCap.bSystemS1;
        bSupportS3 := SystemPowerCap.bSystemS3;
        bSupportS4 := SystemPowerCap.bSystemS4;
      end
      else
        TakeLog('***ERROR in getting System Power Capbilities:'   SysErrorMessage(GetLastError));
    except on E: Exception do
      begin
        MessageDlg(E.Message, mtError, [mbOK], 0);
        TakeLog('***ERROR in getting System Power Capbilities');
      end
    end;      finally
    FreeMem(SystemPowerCap); <=老是出現Invalid Pointer Operation Error
  end;
end;
Error Message:...raised exception class EInvalidPointer with message 'Invalid pointer operation'. Process stopped... EInvalidPointer 根據help說明可能原因:想要free已經free的pointer 或是free兩次(意思相同) 不知道有沒有人遇過類似經驗 討論群組有關的都是提到引入ShareMem unit 不過我想我的情形應該不同 而且傳入傳出也沒有string的問題 參考Windows.pas 中GetSystemPowerStatus的宣告,我想第一次的宣告應該沒有錯
Unit Windows;
...
...
type
  PSystemPowerStatus = ^TSystemPowerStatus;
  _SYSTEM_POWER_STATUS = packed record
    ACLineStatus : Byte;
    BatteryFlag : Byte;
    BatteryLifePercent : Byte;
    Reserved1 : Byte;
    BatteryLifeTime : DWORD;
    BatteryFullLifeTime : DWORD;
  end;
  {$EXTERNALSYM _SYSTEM_POWER_STATUS}
  TSystemPowerStatus = _SYSTEM_POWER_STATUS;
  SYSTEM_POWER_STATUS = _SYSTEM_POWER_STATUS;
  {$EXTERNALSYM SYSTEM_POWER_STATUS}    function GetSystemPowerStatus(var lpSystemPowerStatus: TSystemPowerStatus): BOOL; stdcall;
...
...
@瞭解越多.懂得越少@ 發表人 - chris_shieh 於 2005/03/15 14:51:11
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-03-25 18:15:51 IP:60.248.xxx.xxx 未訂閱
哈囉,我 try 了一下,二種寫法,我都可以過 不過,你貼出來的程式碼,少了二樣東西的宣告,我補一下我的寫法
  BATTERY_REPORTING_SCALE = packed record
    Granularity:  Cardinal;
    Capacity:     Cardinal;
  end;      SYSTEM_POWER_STATE = integer;
另外,就是 SYSTEM_POWER_STATE 的部份比較特別 一開始,我是看 MSDN 所以就這樣寫
  SYSTEM_POWER_STATE = (
    PowerSystemUnspecified,
    PowerSystemWorking,
    PowerSystemSleeping1,
    PowerSystemSleeping2,
    PowerSystemSleeping3,
    PowerSystemHibernate,
    PowerSystemShutdown,
    PowerSystemMaximum);
這樣的話,會有 Access Violation,用 SizeOf 查一下 發現用列舉的話 SYSTEM_POWER_STATE 只有 1 byte 而已知 integer 是 4 bytes 用 C 去 Check 了一下,SYSTEM_POWER_STATE 應該要是 4 bytes 才對 我想應該是這樣造成的,請試試看吧
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-03-29 18:19:42 IP:219.68.xxx.xxx 未訂閱
確定問題是 SYSTEM_POWER_STATE = ( PowerSystemUnspecified, PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown, PowerSystemMaximum); 這樣宣告才會正常 SYSTEM_POWER_STATE = integer; @瞭解越多.懂得越少@
系統時間:2024-04-29 10:33:20
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!