2014-02-24 56 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