如何通过COM与Delphi 7访问C#公共结构

时间:2014-02-24 22:20:08

标签: .net delphi com

在Delphi 7中,我试图使用COM读取一些C#.Net公共结构常量。

我似乎无法正确理解语法。

德尔福代码

我还没有找到任何方法来编写甚至可以针对提取的TLB.pas文件进行编译的代码。此代码无法编译,并显示错误:“Object or class required”

   S := ItemFieldIdentifier.AverageMarketPrice;  

所以,即使C#程序员告诉我这不是一个可实例化的对象,TLB也有这种类型的构造函数,所以我想我尝试实例化。此代码无法使用错误“未声明的标识符”进行编译:

   var
     ItemFieldIdentifier1: ItemFieldIdentifier;
     ...
     ItemFieldIdentifier1 :=  CoItemFieldIdentifier.Create;
     S := ItemFieldIdentifier1.AverageMarketPrice;  

有没有办法让我通过COM访问这些常量,或者C#程序员是否需要创建一个我可以创建然后访问的可实例化对象?

C#代码

    public struct ItemFieldIdentifier
    {
        ...
                    public static readonly string AverageMarketPrice = "AMP";
        ...

然后,在C#中,他们有代码com互操作层

    public class ItemFieldIdentifier
    {
       public string AverageMarketPrice
       {
            get
            {
                 return xxx.Public.ItemCat.ItemFieldIdentifier.AverageMarketPrice; // <-- this is getting the value from the struct.
    }

TLB档案

  DIID__ItemFieldIdentifier: TGUID = '{667FB47F-6394-4ED6-842B-7581184B4138}';
  IID__ItemFieldIdentifier_2: TGUID = '{FBF4AD9B-38B5-3856-ADAC-57DB3198BBE7}'
  CLASS_ItemFieldIdentifier: TGUID = '{3A9E41E3-A509-483B-A212-6A507EA29B5B}';

  _ItemFieldIdentifier = dispinterface;
  _ItemFieldIdentifier_2 = interface;
  _ItemFieldIdentifier_2Disp = dispinterface; 

    ItemFieldIdentifier = _ItemFieldIdentifier_2;

    // *********************************************************************//
    // DispIntf:  _ItemFieldIdentifier
    // Flags:     (4096) Dispatchable
    // GUID:      {667FB47F-6394-4ED6-842B-7581184B4138}
    // *********************************************************************//
  _ItemFieldIdentifier = dispinterface
    ['{667FB47F-6394-4ED6-842B-7581184B4138}']
    ...
    property AverageMarketPrice: WideString readonly dispid 45;
    ...

  end;

    // *********************************************************************//
    // Interface: _ItemFieldIdentifier_2
    // Flags:     (4432) Hidden Dual OleAutomation Dispatchable
    // GUID:      {FBF4AD9B-38B5-3856-ADAC-57DB3198BBE7}
    // *********************************************************************//
      _ItemFieldIdentifier_2 = interface(IDispatch)
        ['{FBF4AD9B-38B5-3856-ADAC-57DB3198BBE7}']
      end;


    // *********************************************************************//
    // Interface: _ItemFieldIdentifier_2
    // Flags:     (4432) Hidden Dual OleAutomation Dispatchable
    // GUID:      {FBF4AD9B-38B5-3856-ADAC-57DB3198BBE7}
    // *********************************************************************//
      _ItemFieldIdentifier_2 = interface(IDispatch)
        ['{FBF4AD9B-38B5-3856-ADAC-57DB3198BBE7}']
      end;

    // *********************************************************************//
    // DispIntf:  _ItemFieldIdentifier_2Disp
    // Flags:     (4432) Hidden Dual OleAutomation Dispatchable
    // GUID:      {FBF4AD9B-38B5-3856-ADAC-57DB3198BBE7}
    // *********************************************************************//
      _ItemFieldIdentifier_2Disp = dispinterface
        ['{FBF4AD9B-38B5-3856-ADAC-57DB3198BBE7}']
      end;

    // *********************************************************************//
    // The Class CoItemFieldIdentifier provides a Create and CreateRemote method to          
    // create instances of the default interface _ItemFieldIdentifier_2 exposed by              
    // the CoClass ItemFieldIdentifier. The functions are intended to be used by             
    // clients wishing to automate the CoClass objects exposed by the         
    // server of this typelibrary.                                            
    // *********************************************************************//
      CoItemFieldIdentifier = class
        class function Create: _ItemFieldIdentifier_2;
        class function CreateRemote(const MachineName: string): _ItemFieldIdentifier_2;
      end;

2 个答案:

答案 0 :(得分:1)

  

所以,即使C#程序员告诉我这不是一个可实例化的对象,TLB也有这种类型的构造函数,所以我想我尝试实例化。此代码无法使用错误“未声明的标识符”进行编译

这很奇怪,因为ItemFieldIdentifier已明确定义(它是_ItemFieldIdentifier_2的别名)。

CoItemFieldIdentifier.Create()会返回_ItemFieldIdentifier_2,因此您可以尝试声明您的变量。但是,_ItemFieldIdentifier_2没有声明任何成员。因此,假设ItemFieldIdentifier_2派生自C#端的ItemFieldIdentifier,您可以尝试在Delphi端从_ItemFieldIdentifier_2转换为_ItemFieldIdentifier

var
  ItemFieldIdentifier1: _ItemFieldIdentifier;
...
ItemFieldIdentifier1 := CoItemFieldIdentifier.Create as _ItemFieldIdentifier;
S := ItemFieldIdentifier1.AverageMarketPrice;  

或者:

var
  ItemFieldIdentifier1: _ItemFieldIdentifier_2;
...
ItemFieldIdentifier1 := CoItemFieldIdentifier.Create;
S := (ItemFieldIdentifier1 as _ItemFieldIdentifier).AverageMarketPrice;  

答案 1 :(得分:0)

Delphi 7不处理vtRecord OLE类型。此类型与C#struct类型匹配。

我怀疑你应该使用标记为COMVisible=True的C#类作为数据对象,从Delphi访问。

或者您可以尝试使用更新的TLBEXP工具生成TLB .pas文件。我发现最新版本能够正确处理这些struct类型。