2012-04-29 21 views
1

我試圖從託管調用方調用C++/CLI類方法。託管程序集定義了一個類,它是C++/CLI函數的輸入類型,並通過OnPropertyChanged事件響應託管類中變量的更改。當其中一個事件更改處理程序觸發它調用傳遞數據的C++/CLI。由託管程序集調用C++/CLI導致的循環依賴關係

C#:

namespace managedA 
{ 
    class clsA 
    { 
     //The rest of clsA defined elsewhere 
     partial void initialise() 
     { 
      this.PropertyChanged += delegate(object o, System.ComponentModel.PropertyChangedEventArgs args) 
      { 
       if (args.PropertyName == "myvar") 
       { 
        CalcMyVar(); 
       } 
      } 
     } 

     void CalcMyVar() 
     { 
      cppcli::Calc _calc = new cppcli::Calc(); 
      _calc.DoSomething(this); 
     } 
    } 
} 

C++/CLI:

namespace cppcli 
{ 
public ref class Calc  
    { 
    public: 

     managed::clsA^DoSomething(managed::clsA^input) 
     { 
      ... 
     } 
    } 
} 

我的問題是由管理呼叫者對本身通過C++/CLI的循環依賴關係引起的。我試圖在被調用者(cppcli:Calc)繼承的中間項目中聲明一個接口類,但這不起作用,因爲中間項目總是需要知道managed::clsAcppcli::Calc被聲明的位置。似乎我聲明cppcli::Calc(例如摘錄managed::clsAObject),我總是最終需要在聲明的某處參考managed::ClsA。我該如何聲明cppcli::Calc以便在聲明中抽象類型?

謝謝。

+0

你將不得不自下而上。在你的C++/CLI代碼中聲明一個'interface class',它聲明瞭你的C#代碼可以實現的接口。 DoSomething()如何返回對接口的*具體*實例的引用是你必須考慮的事情。這不能真正起作用。 –

回答

2

好吧,我不會將C++/CLI稱爲非託管,並將您的應用程序的其他部分作爲託管對象,因爲所有特定的C++/CLI代碼都是託管的。只有你使用的本地C++代碼是非託管的。至少我是這麼理解的。無論如何,繼續前進,如果你的應用程序的C++/CLI部分像一個實用程序一樣工作,那麼我會建議在你在應用程序中繼承的C++/CLI部分中聲明一個基類(「管理」稱之爲)你的軟件的一部分。這樣,應用程序部分就包含並從C++/CLI部分繼承,但C++/CLI部分不需要知道應用程序層。爲了給一個未經測試例如:

C++/CLI代碼

public ref class base 
{ 
public: 
    int a; 
}; 

public ref class Calc 
{ 
public: 
    static void DoSomething(base^ p_base) 
    { 
     p_base.a = 5; 
    } 
} 

應用層

//Include your C++/CLI code 
public ref class app_class : public base 
{ 
    void do_something() 
    { 
     Calc::DoSomething(this); 
    } 
} 

反正我是沒編譯這個,但我認爲你的想法。

+0

謝謝你。我會試一試,讓你知道我如何繼續。 – pdm2011

+0

最後,我在C++/CLI中創建了一箇中間類,它用作原始C++/CLI類('managed :: clsA')中定義的類型實例的容器。 – pdm2011

+0

通過這種方式,應用程序依賴於中間類,並從中請求業務對象實例(原始帖子中的「類Calc」),而無需直接依賴業務層。 這是通過註冊業務類的類型並使用反射('ConstructorInfo')創建這些類型的實例來實現的。 – pdm2011