2012-05-29 22 views
2

我想使用C++ lib與C#中的非託管代碼。我發現在stackoverflow上的一些文章是如何做到的。用這種方式它可以工作,但我需要一些解決方案來定義C#代碼中的C++類的抽象函數(具體來說 - 我的C++庫函數必須在C#中調用函數)。雙向通信beetwen C#代碼和非託管C++ lib

問候 卡米爾

回答

0

是具體的 - 我的圖書館C++函數必須調用在C#中的功能)。

這是完全正常,轉向在函數指針,但是......

,但我需要一些解決方案,從C++類在C#中

NO WAY定義抽象功能。你所能做的只是實現與DLL的交互 - 而不是「編譯器工件」,甚至沒有標準化(編譯器之間的差異)。你可以坐下來學習C++,C++中的子類 - 這個C++可以被託管C++(現在的C++/CLR),所以你可以很好地調用託管代碼。

但是,不能,您不能在.NET中對存儲在C++編譯器「.lib」artefact中的類進行子類化。

+0

就可以了,但是這是非常棘手。回想一下UnrealEngine的UnrealScript。你可以用腳本語言定義類,這些類可以從C++的類派生。與.NET(C++/CLI,C#)和「本地」C++相同。這很難,但看到我的問題是「解決方法」。 –

+0

我的理解是這個問題是類繼承,而不是「假類」a.k.a.接口的實現。這可能工作,但否則 - 這太髒了調試。 – TomTom

+0

我沒有downvote你的答案,因爲你得到了正確的,我也正確:) :)當然,託管/非託管代碼(在繼承方面)的直接混合是不可能的,但我相信這個「​​橋樑」託管的世界是OP想要的。我用腳本語言做了這個,我做了很多與.NET的互操作,所以這裏是我的解決方法。 –

3

很酷的問題。要想到這個想法,你應該考慮以下一般情況。你有一個大的C++項目,你想用腳本來擴展它。在你的情況下,「腳本」是.NET/CLR。

您有:

namespace Native { 

class NativeInterface 
{ 
public: 
    /// Yes, no implementation here, in the "native world" 
    virtual void NativeMethod() = 0; 

    /// Some other method(s) you'd like to call 
    virtual void ConcreteMethod() { cout << "Hello" << endl; } 
}; 

} // namespace Native 

您必須對本土:: NativeInfterface的C++/CLI包裝:

namespace Managed 
{ 
    ref class NativeInterface 
    { 
    public: 
     virtual void NativeMethod() abstract; 

     virtual void ConcreteMethod() { NativeObj->ConcreteMethod(); } 
    public: 
     Native::NativeInterface* NativeObj; 
    }; 
} /// namespace managed 

你想在C#中要做到:

namespace Managed { 

public class MyNETImplementation: NativeInterface 
{ 
    override void NativeMethod() 
    { 
     DoTheStuff_UsingNativeCode(); // possibly, call the ConcreteMethod 
    } 
} 

} // namespace Managed 

關鍵的是你想要將MyNETImplementation的「指針」傳遞給本地世界。

因此,您應該在C++/CLI中實現棘手的NativeInterfaceImpl類,該類將持有對MyNETImplementation的託管引用,並且它將調用適當的方法。

首先嚐試:

namespace Managed { 

/// C++/CLI in mixed-mode assembly 
class NativeInterfaceImpl: public NativeInterface 
{ 
public: 
    NativeInterfaceImpl(Managed::NativeInterface^ Obj) { ManagedObj = Obj; } 

    /// Native implementation to call the managed class 
    virtual void NativeMethod() 
    { 
     Obj->NativeMethod(); 
    } 
public: 
    gcroot<Managed::NativeInterface^> ManagedObj; 
}; 

} // namespace Managed 

是的,這是棘手的,也有關於如何通過參數的許多問題,但封送處理問題在本網站上的細節考慮。

忘了添加如何使用託管指針NativeInterfaceImpl。如果使用「gcnew」關鍵字進行分配,則必須在使用前「釘住」它們。

Managed::NativeInterface^ obj = gcnew NativeInterfaceImpl(gcnew MyNETImplementation()); 
pin_ptr<NativeInterface> pinned = obj; 

/// void SomeNativeFunction(NativeInterface*); 
SomeNativeFunction(pinned); 

EDIT(收尾):

有一對夫婦引用,其中有些過時(它們與託管C++,不是C++/CLI),但還是很容易適應的。

Calling managed code from unmanaged

Second version of managed<->unmanaged calls

+4

是的,建立一個C++/CLI橋樑:=) –

+1

看起來它太難以進入常見問題:)但它似乎沒問題,它工作正常。 –

+0

Viktor感謝您的回答。我正在嘗試使用您的提案,但我有一個問題。我想應該在C#部分中實現代碼的最後一個源代碼(您使用gcnew的地方)。但在C#中,我不能使用像gcnet和指針。你能告訴我,如果我正確理解你的話嗎? – kolumb