2011-03-21 47 views
2

然而,我正在爲C++ CLI編寫一個封裝器,以便爲我們的應用程序提供一些新的部件(用C#編寫)保存並輕鬆訪問舊的本機庫。因此我需要將一些結構從c#傳遞給C++。這些結構在C++ Cli(dotnet)和C++中定義。將DOTNET封裝爲原生C++ CLI BestWay以傳遞結構?

實施例:

\\C+++ 
typedef struct 
{               
INFO16 jahr ; 
INFO8 monat ; 
INFO8 tag ; 
INFO8 stunde ; 
INFO8 minute ; 
} 
SDATUM; 

\\c++ cli 
[StructLayout(LayoutKind::Explicit)] 
public value struct SDATUM 
{ 
public: 
    [FieldOffset(0)] 
    UInt16 jahr; 
    [FieldOffset(2)] 
    Byte monat; 
    [FieldOffset(3)] 
    Byte tag; 
    [FieldOffset(4)] 
    Byte stunde; 
    [FieldOffset(5)] 
    Byte minute; 
}; 

現在我提供在C++ CLI一些功能,其接受這種類型的dotnet型SDATUM在由值通的形式,其通過引用(sdatum%)和指針sdatum *像有相應的天然功能。我需要轉換/轉換這些結構?

回答

0

我發現了另一個非常簡單,不需要複製數據的解決方案。 你可以把它想一個C SDATUM這樣本機的功能:

//signature 
void someFunction(SDATUM datum); 

void someFunctionWrapper(SDATUM datum){ 
pin_ptr<SDATUM> datum_pin=&datum; 


//::SDATUM refers to the C-Type 
someFunction(*(::SDATUM*)datum_pin); 
} 

我測試了它和它的作品,因爲這兩個SDATUM的Structs具有相同的比特結構。因爲我只打電話 簡短的本地功能,我認爲碎片是沒有問題的。

2

我不會做任何鑄造。相反,編寫一個包含SDATUM的ref類。公開設置底層SDATUM的方法和屬性。從C#端開始,使用這個ref類(或更好的方法是創建一個此類實現的接口,並使C#端與接口一起工作)。在C++/CLI中,您可以訪問本機版本的類並根據需要將它傳遞給本機方法。

2

請注意,C++和.NET的複製語義根本不同:.NET使用垃圾收集共享引用和C++使用複製構造函數。

C++/CLI不會讓你使用本地對象作爲託管類的成員,你必須使用指針。所以我將使用boost共享指針來模仿.NET語義。

這可以被抽象掉。下面是我用揭露C++類的.NET世界級的:

template <typename T> 
ref class Handle 
{ 
    boost::shared_ptr<T>* t; 

    !Handle() 
    { 
     if (t != nullptr) 
     { 
      delete t; 
      t = nullptr; 
     } 
    } 

    ~Handle() { this->!Handle(); } 

public: 
    Handle() : t(new boost::shared_ptr<T>((T*)0)) {} 

    Handle(T* ptr) : t(new boost::shared_ptr<T>(ptr)) {} 

    Handle% operator=(T* p) 
    { 
     if (p != t->get()) t->reset(p); 
     return *this; 
    } 

    T* get() { return t->get(); } 

    // Remember that operators are static in .NET 
    static boost::shared_ptr<T> operator->(Handle% h) { return *h.t; } 

    T& reference() { return *t->get(); } 
    T const& const_reference() { return *t->get(); } 
}; 

然後你可以使用:

ref class MyStruct 
{ 
public: 
    // Expose your .NET interface here, make it use the handle variable. 

internal: 
    Handle<Native::MyStruct> handle; 
}; 

,並在你的C++代碼沒有任何限制使用handle成員變量。它不會在.NET中顯示。然後你可以以.NET的方式公開屬性,訪問器,操作符等等。

+0

這是一個非常好的模板,但不幸的是我無法使用提升。我會盡力實現它,而不是提升 – 2011-03-24 08:05:56