2011-10-25 59 views
1

我很新的DLL對象,我到處搜索,找不到正確的答案。 我正在做一個微軟RMS的小插件,它會自動調用我的dll中的函數Process,IDispach參數傳遞當前會話的詳細信息。COM對象和不同版本的DLL

我使用的接口從QSRules.dll(組件>導入>組件>輸入庫...添加到項目)。 它創建TLB與所有的引用等

​​

與軟件2.01版完美的作品,但試圖利用對2.02版相同的功能,當它與「接口不支持」崩潰文件。 QSRules.dll有更新的版本和所有類的GUID是不同的。

我試圖與休耕代碼:

procedure TRefreshScreenRefreshScreen.Process(const Session: IDispatch); 
begin 

    if Supports(Session, QSRules_TLB_2_0_0_151.SessionClass) then 
    Begin 
     CodeSite.Send(csmLevel1, '(Session as SessionClass).Cashier.Name', (Session as QSRules_TLB_2_0_0_151.SessionClass).Cashier.Name); 
     CodeSite.Send(csmLevel1, '(Session as SessionClass).Cashier.Number', (Session as QSRules_TLB_2_0_0_151.SessionClass).Cashier.Number); 
    end else 

    if Supports(Session, QSRules_TLB_2_0_0_105.SessionClass) then 
    Begin 
     CodeSite.Send(csmLevel1, '(Session as SessionClass).Cashier.Name', (Session as QSRules_TLB_2_0_0_105.SessionClass).Cashier.Name); 
     CodeSite.Send(csmLevel1, '(Session as SessionClass).Cashier.Number', (Session as QSRules_TLB_2_0_0_151.SessionClass).Cashier.Number); 
    end 

end; 

是有4個或5個不同版本的DLL都具有不同的GUID的BU 98的代碼%的所有的人之間的相同。 這樣做是不合理的乘法代碼。

有什麼辦法可以縮短它嗎?

我也試過

procedure TRefreshScreenRefreshScreen.Process(const Session: IDispatch); 
var 
_Session: SessionClass; 
begin 

    if Supports(Session, QSRules_TLB_2_0_0_151.SessionClass) then 
    _Session = (Session as QSRules_TLB_2_0_0_151.SessionClass) 

    else if Supports(Session, QSRules_TLB_2_0_0_105.SessionClass) then 
     _Session = (Session as QSRules_TLB_2_0_0_105.SessionClass); 

    with _Session do 
    Begin 
     CodeSite.Send(csmLevel1, '_Session.Cashier.Name', Cashier.Name); 
     CodeSite.Send(csmLevel1, '_Session..Cashier.Number', Cashier.Number); 
    End; 

end; 

但這不起作用,因爲變量的類型只能從唯一的單位進行分配。

任何幫助表示讚賞!

+1

聽起來像一個非常可怕的COM接口!你不能使用單一版本的DLL來分發你的應用程序,並且使用並行COM來確保你得到你想要的版本。支持多個版本將是可怕的。你會如何測試? –

回答

0

終於搞定了!只要分享答案,以防其他人尋找它。

成功的關鍵是「後期綁定」,這意味着你不使用接口。

procedure TRefreshScreenRefreshScreen.Process(const Session: IDispatch); 
var 
_Session: Variant; 
begin 

    _Session := Session; 

    CodeSite.Send(csmLevel1, '_Session.Cashier.Name', _Session.Cashier.Name); 
    CodeSite.Send(csmLevel1, '_Session.Cashier.Number', _Session.Cashier.Number); 

end; 

隨着Variant變量的功能不被編譯,但在運行時檢查,所以你要確保拼寫正確,因爲智能感知不檢查它。

工程就像一個夢!

無論如何,謝謝你們!

0

你說接口在不同版本中有不同的guid。只要更新的接口來自舊接口,這就完全正常了。實際上是這樣嗎?如果他們這樣做,那麼你可以通過將你的Session對象轉換爲實際定義出納成員的任何接口來簡化你的代碼。除非接口不相互派生,否則不需要將其轉換爲每個單獨的接口類型。你能顯示實際的接口聲明嗎?

0

出納聲明從v2.0.0.105

_Cashier = interface(IDispatch) 
    ['{AA84B4FB-AA41-4423-A763-59D0723ED52B}'] 
    function Get_Session: _SessionClass; safecall; 
    function Get_CashDrawer: _CashDrawer; safecall; 
    function Get_OverShortLimitType: overshortlimitEnum; safecall; 
    function Get_MaxOverShortAmount: Currency; safecall; 
    function Get_MaxOverShortPercent: Double; safecall; 
    function Get_SecurityLevel: Smallint; safecall; 
    function Get_HasPrivilege(var CashierPrivilege: cashierprivilegesEnum): WordBool; safecall; 
    function Get_FailedLogOnAttempts: Integer; safecall; 
    function Get_EmailAddress: WideString; safecall; 
    function Get_Messages: _CashierMessages; safecall; 
    function Get_UnreadMessageCount: Integer; safecall; 
    function Get_Name: WideString; safecall; 
    function Get_FirstName: WideString; safecall; 
    function Get_LastName: WideString; safecall; 
    function Get_ReturnLimit: Currency; safecall; 
    function Get_FloorLimit: Currency; safecall; 
    function Get_ID: Integer; safecall; 
    function Get_CashDrawerNumber: Smallint; safecall; 
    function Get_Loaded: WordBool; safecall; 
    function Get_Number: WideString; safecall; 
    property Session: _SessionClass read Get_Session; 
    property CashDrawer: _CashDrawer read Get_CashDrawer; 
    property OverShortLimitType: overshortlimitEnum read Get_OverShortLimitType; 
    property MaxOverShortAmount: Currency read Get_MaxOverShortAmount; 
    property MaxOverShortPercent: Double read Get_MaxOverShortPercent; 
    property SecurityLevel: Smallint read Get_SecurityLevel; 
    property HasPrivilege[var CashierPrivilege: cashierprivilegesEnum]: WordBool read Get_HasPrivilege; 
    property FailedLogOnAttempts: Integer read Get_FailedLogOnAttempts; 
    property EmailAddress: WideString read Get_EmailAddress; 
    property Messages: _CashierMessages read Get_Messages; 
    property UnreadMessageCount: Integer read Get_UnreadMessageCount; 
    property Name: WideString read Get_Name; 
    property FirstName: WideString read Get_FirstName; 
    property LastName: WideString read Get_LastName; 
    property ReturnLimit: Currency read Get_ReturnLimit; 
    property FloorLimit: Currency read Get_FloorLimit; 
    property ID: Integer read Get_ID; 
    property CashDrawerNumber: Smallint read Get_CashDrawerNumber; 
    property Loaded: WordBool read Get_Loaded; 
    property Number: WideString read Get_Number; 
    end; 

出納聲明從v2.0.0.151

_Cashier = interface(IDispatch) 
    ['{39B2C128-00F1-4834-B1A4-05197C708BD9}'] 
    function Get_Session: _SessionClass; safecall; 
    function Get_CashDrawer: _CashDrawer; safecall; 
    function Get_OverShortLimitType: overshortlimitEnum; safecall; 
    function Get_MaxOverShortAmount: Currency; safecall; 
    function Get_MaxOverShortPercent: Double; safecall; 
    function Get_SecurityLevel: Smallint; safecall; 
    function Get_HasPrivilege(var CashierPrivilege: cashierprivilegesEnum): WordBool; safecall; 
    function Get_FailedLogOnAttempts: Integer; safecall; 
    function Get_EmailAddress: WideString; safecall; 
    function Get_Messages: _CashierMessages; safecall; 
    function Get_UnreadMessageCount: Integer; safecall; 
    function Get_Name: WideString; safecall; 
    function Get_FirstName: WideString; safecall; 
    function Get_LastName: WideString; safecall; 
    function Get_ReturnLimit: Currency; safecall; 
    function Get_FloorLimit: Currency; safecall; 
    function Get_ID: Integer; safecall; 
    function Get_CashDrawerNumber: Smallint; safecall; 
    function Get_Loaded: WordBool; safecall; 
    function Get_Number: WideString; safecall; 
    function Get_PasswordAge: Integer; safecall; 
    function Get_ReminderPeriod: Integer; safecall; 
    function Get_PasswordResetFlag: WordBool; safecall; 
    function Get_IsPasswordChanged: WordBool; safecall; 
    procedure Set_IsPasswordChanged(var Param1: WordBool); safecall; 
    function Get_TimecardID: Integer; safecall; 
    procedure Set_TimecardID(var Param1: Integer); safecall; 
    function ValidatePassword(var Password: WideString): WordBool; safecall; 
    function IsPwdDuplicated(var CashierNumber: Integer; var Password: WideString): WordBool; safecall; 
    property Session: _SessionClass read Get_Session; 
    property CashDrawer: _CashDrawer read Get_CashDrawer; 
    property OverShortLimitType: overshortlimitEnum read Get_OverShortLimitType; 
    property MaxOverShortAmount: Currency read Get_MaxOverShortAmount; 
    property MaxOverShortPercent: Double read Get_MaxOverShortPercent; 
    property SecurityLevel: Smallint read Get_SecurityLevel; 
    property HasPrivilege[var CashierPrivilege: cashierprivilegesEnum]: WordBool read Get_HasPrivilege; 
    property FailedLogOnAttempts: Integer read Get_FailedLogOnAttempts; 
    property EmailAddress: WideString read Get_EmailAddress; 
    property Messages: _CashierMessages read Get_Messages; 
    property UnreadMessageCount: Integer read Get_UnreadMessageCount; 
    property Name: WideString read Get_Name; 
    property FirstName: WideString read Get_FirstName; 
    property LastName: WideString read Get_LastName; 
    property ReturnLimit: Currency read Get_ReturnLimit; 
    property FloorLimit: Currency read Get_FloorLimit; 
    property ID: Integer read Get_ID; 
    property CashDrawerNumber: Smallint read Get_CashDrawerNumber; 
    property Loaded: WordBool read Get_Loaded; 
    property Number: WideString read Get_Number; 
    property PasswordAge: Integer read Get_PasswordAge; 
    property ReminderPeriod: Integer read Get_ReminderPeriod; 
    property PasswordResetFlag: WordBool read Get_PasswordResetFlag; 
    property IsPasswordChanged: WordBool read Get_IsPasswordChanged write Set_IsPasswordChanged; 
    property TimecardID: Integer read Get_TimecardID write Set_TimecardID; 
    end; 

正如你可以看到有在以後的版本中添加一些東西,但有毫無疑問,我需要在調用它們的函數時檢查軟件版本。收銀員只有25-30種類型之一,所以如果我必須爲所有版本編寫相同的基本實現......大任務,以及在後期階段進行修改的可怕代碼。