2014-02-24 54 views
1

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

我似乎无法得到正确的语法。

Delphi代码

我还没有发现任何方式来编写代码,甚至会打击编译提取TLB.pas文件。此代码失败,出现错误编译:“对象或类要求”

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; 
+0

这并不会让很多感。您发布的.tlb将无法编译。 _ItemFieldIdentifier_2的多重定义。你可以仔细检查你发布的内容是否准确。 –

+0

谢谢你刺伤这件事,大卫。我知道发布编译的真实代码是多么重要(特别是当我希望你会看看它:-)),但是整个.pas文件太大而无法在这里发布。我发布了我认为是一个有效的修剪版本。尽管如此,不要猜测。雷米让我走了。再次感谢。 – Tom

回答

1

So, even though the C# programmer tells me that this isn't an instantiatable object, the TLB has a constructor for this type, so I figured I try instantiating. This code failed to compile with the error "Undeclared identifier"

即奇数时,因为ItemFieldIdentifier明确定义(它是一个别名_ItemFieldIdentifier_2)。

CoItemFieldIdentifier.Create()返回_ItemFieldIdentifier_2,所以你可以尝试声明你的变量。但是,_ItemFieldIdentifier_2没有声明任何成员。因此,假设ItemFieldIdentifier_2ItemFieldIdentifier在C#侧派生,你可以尝试在德尔福侧做从_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; 
+0

哇!伟大的作品,雷米!谢谢。 – Tom

+0

如果这是解决方案,有些事情是非常错误的。 .tlb导入程序是否错误。如果是这样,我会通过修复接口声明来处理这个问题,以便代码可以在没有强制转换的情况下编写。 –

0

vtRecord OLE类型是ñ由Delphi 7处理。此类型匹配C#struct类型。

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

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

+0

好的建议,Arnaud,尝试更新版本的Delphi。我只是尝试了这一点,充满希望,但并未解决问题。 (还是)感谢你的建议。 – Tom