2011-10-25 60 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种类型之一,所以如果我必须为所有版本编写相同的基本实现......大任务,以及在后期阶段进行修改的可怕代码。