2013-08-01 95 views
1

我想用C++/CLI包裝本地庫。它與原始類型一起工作。但在以下情況下,它更復雜:包裝C#C++

interface ISampleInterface 
{ 
    void SampleMethod(); 
} 

public ref class NativeClassWrapper { 
    NativeClass* m_nativeClass; 

public: 
    NativeClassWrapper() { m_nativeClass = new NativeClass(); } 
    ~NativeClassWrapper() { delete m_nativeClass; } 
    void Method(ISampleInterface ^i) { 
     ??? 
     m_nativeClass->Method(i); 
    } 
}; 

如何包裝這?由於本機代碼C++不知道ISampleInterface型...(與虛擬類相同的問題)

謝謝你。

+1

爲什麼'NativeClass :: Method'需要訪問'ISampleInterface'?正如你所說,它*不能*使用它,所以你需要一種方法來改變設計。 – SteveLove

+0

本機代碼需要訪問實現ISampleInterface的類。在這個例子中,它是一個接口,但它可以是一個類。本設計中的問題是本地代碼不知道C++/CLI操作的元素的類型。我不知道如何解決這個問題。設計使用哪種設計?謝謝你的幫助。 – user1886318

回答

2

有在代碼片段一些錯誤。讓我們用乾淨的例子開始,首先宣佈了本機類:

#pragma unmanaged 
class INativeInterface { 
public: 
    virtual void SampleMethod() = 0; 
}; 

class NativeClass { 
public: 
    void Method(INativeInterface* arg); 
}; 

而且管理界面:

#pragma managed 
public interface class IManagedInterface 
{ 
    void SampleMethod(); 
}; 

所以,你需要的是一個從INativeInterface派生,這樣就可以通過一個本地包裝類它的一個實例NativeClass :: Method()。這個包裝器所要做的只是將調用委託給相應的託管接口方法。通常是一個簡單的單線程,除非參數類型需要轉換。就像這樣:

#pragma managed 
#include <msclr\gcroot.h> 

class NativeInterfaceWrapper : public INativeInterface { 
    msclr::gcroot<IManagedInterface^> itf; 
public: 
    NativeInterfaceWrapper(IManagedInterface^ arg) : itf(arg) {}; 
    virtual void SampleMethod() { 
     itf->SampleMethod(); 
    } 
}; 

現在你的方法實現變得容易:

void Method(IManagedInterface^ i) { 
    NativeInterfaceWrapper wrap(i); 
    m_nativeClass->Method(&wrap); 
} 
+0

非常感謝你,它工作正常。你知道在JAVA中msclr :: gcroot的等價物嗎? – user1886318

+0

@ user1886318:它看起來像'jobject'大致相當於'GCHandle',你需要製作自己的RAII包裝器,以確保它在本機代碼不再需要時自動釋放。或者借一個,但我不認爲有一個官方JNI認可的包裝。 –

2

如果你的原生類需要回調到.NET代碼,您需要使用gcroot模板。 Wuth可以將託管對象存儲在非託管類中。在這個非託管類中,您可以使用本機「回調」,然後使用存儲在`gcroot'中的成員回調到託管代碼(ISampleInterface)中。

參見:

+0

謝謝你,的確我必須使用gcroot。 – user1886318