【问题标题】:Maximum number limitation of COM+ function parametersCOM+ 函数参数的最大数量限制
【发布时间】:2011-10-11 19:17:57
【问题描述】:

我使用 Delphi 类型库来创建 COM+ 应用程序。当我为一个函数调用创建数字 78 参数时出现访问冲突错误。我意识到 COM+ 函数的参数数量是有限制的。所以之后,我必须使用类型化结构/记录来打包参数。然后传递一条记录而不是简单数据类型参数的数量。

你知道这个限制吗?你有什么建议?

我对 Struct/Record 进行了更多测试,然后我安装了新组件并在调用它时出现错误:

我调用函数:

ReturnVaule := Clients.updClient2(EmploymentApp.SessionID,
                                MyClientDetails,
                                dtLastModificationDate,
                                ClientServices,
                                ClientRequestors,
                                ClientQuestionnaires);

我得到了错误:

“一个空引用指针被传递给存根”

【问题讨论】:

    标签: delphi com+ typelib


    【解决方案1】:

    我不相信 Delphi 或 COM+ 有任何这样的限制。我不确定是什么导致了您的错误,但我认为您需要更详细地描述您所做的事情。

    无论如何,拥有这么多参数的方法是不明智的。超过大约 4 或 5 个已经在拉伸它。将此事件作为一个温和的提示,以更易于管理的方式重新考虑您的设计。

    【讨论】:

    • 我认为错误是由参数数量引起的原因是:如果我在第 78 位添加任何类型的参数,则会引发错误。如果我删除最后一个,错误就会消失。我放很多参数的原因是因为COM+函数不会接受任何自定义的类或类型作为参数类型。
    • COM+ 函数将接受类型库中声明的记录(结构)参数类型。
    • "对于暴露给外界的方法,您不能在参数中使用用户定义的数据类型。相反,您可以使用 VARIANT 支持的 Safearrays。" 这是我发现并测试为合理的.
    • 你不能将具有这么多参数的方法真实地暴露给外界。这样做是不人道的。相反,应该考虑的是在一个单独的 COM 对象中传递这些参数,并将所有参数公开为属性。我希望您遇到了 IDE 错误,而不是 COM+ 或 Delphi 中的限制。但是你还没有说 AV 发生在哪里。是在 Delphi IDE 中还是在运行时?
    • 我在 Delphi 5 和 Delphi XE2(最新版本)中对此进行了测试。他们都对“类型库”有同样的问题。所以我可以说 IDE 没有捕捉到这个错误。另一方面,我删除了 {$R *.TLB} 这意味着我不会使用类型库并手动设置所有内容。然后我可以放更多的参数,编译构建成功。但是,我不能让它与组件服务一起运行。
    【解决方案2】:

    如您所说,您可以使用类型库编辑器来声明您的记录类型,然后修改您的方法以使用该类型的参数。

    编辑:类型库编辑器的示例屏幕截图:

    类型库编辑器中的类型库声明生成以下代码(摘录):

    type
    
    // *********************************************************************//
    // Forward declaration of types defined in TypeLibrary
    // *********************************************************************//
      ITest = interface;
      ITestDisp = dispinterface;
    
    // *********************************************************************//
    // Declaration of CoClasses defined in Type Library
    // (NOTE: Here we map each CoClass to its Default Interface)
    // *********************************************************************//
      Test = ITest;
    
    
    // *********************************************************************//
    // Declaration of structures, unions and aliases.
    // *********************************************************************//
      TestRecord = packed record
        Field1: Integer;
        Field2: WideString;
        Field3: TDateTime;
      end;
    
    
    // *********************************************************************//
    // Interface: ITest
    // Flags:     (4416) Dual OleAutomation Dispatchable
    // GUID:      {F3EA5C38-23A6-4919-A51F-31C46DB6012D}
    // *********************************************************************//
      ITest = interface(IDispatch)
        ['{F3EA5C38-23A6-4919-A51F-31C46DB6012D}']
        procedure TestMethod(TestParam: TestRecord); safecall;
      end;
    
    // *********************************************************************//
    // DispIntf:  ITestDisp
    // Flags:     (4416) Dual OleAutomation Dispatchable
    // GUID:      {F3EA5C38-23A6-4919-A51F-31C46DB6012D}
    // *********************************************************************//
      ITestDisp = dispinterface
        ['{F3EA5C38-23A6-4919-A51F-31C46DB6012D}']
        procedure TestMethod(TestParam: {??TestRecord}OleVariant); dispid 201;
      end;
    

    【讨论】:

    • 其实经过多次测试,我发现我唯一能用的就是Variant。也许我也可以使用接口,但它需要更多的编码工作。
    • 您可以使用类型库编辑器在类型库中简单地定义记录类型。
    【解决方案3】:

    最后,我使用 Variant 参数来传递大部分参数,然后将它们作为数组读出。它工作正常,但要知道数组的索引映射到哪个参数并不容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-10
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      • 2016-06-06
      • 2014-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多