簡體   English   中英

將c ++ / CLI模板化包裝器暴露給c#

[英]expose c++/CLI templated wrapper to c#

我目前正在開發一個可視化編輯器來構建有限狀態機。 核心是c ++,因為構建的FSM將在游戲中運行。 編輯器是c#。 我能夠獲得一個CLI包裝器,所以我可以在c#端構建我需要的所有東西。 我要做的最后一件事是能夠將模板化的類暴露給c#。

我從創建托管類開始:

template <typename T>
public ref class TestTemp
{
private:
    ClassToWrap<T>* m_val;
public:

    TestTemp(T val) : 
    {
        m_val = new ClassToWrap<T>();
    }
}

然后,因為模板是在編譯時生成的,所以我強制生成具有模板特化的類型。

template ref class FSMWrapper::TestTemp<float>;

我試圖在幾個地方專門化,cpp,header,也是在main以防萬一,我甚至嘗試在main中的特定實例化,如下所示:

FSMWrapper::TestTemp<float> t(10.0f);

我甚至試圖明確告訴導出符號,就像我在常規c ++中所做的那樣,但編譯器抱怨我不能用托管類型做到這一點。

在所有這些之后,我沒有設法讓符號出現在c#名稱空間中,(其他一切都出現了,所以是的,包裝器按預期工作)。

另外,如果我在包裝器中刪除模板並將其稱為TestTempFloat並在內部強制實現float的實例化。

public ref class TestTempFloat
{
private:
    ClassToWrap<float> m_val;
public:

    TestTempFloat(float val) : 
    {
        m_val = new ClassToWrap<float>();
    }
};

我想做什么,甚至可能嗎? 通過谷歌搜索看起來像是,但人們只是說,將其包裝在CLI類型中並強制生成符號。 如果可能我做錯了什么?

如果不可能,我將只需手動進行專門的包裝,不是很漂亮,但我知道它有效。

我還嘗試將其包裝在通用而不是模板中,但是我不能將T泛型類型作為模板類型提供。

PS:我知道沒有一個析構函數來釋放內存,這只是一個虛擬測試來保持示例簡短。

如果你實現了模板類的完整子類,那應該可以解決問題。 您將需要實現所有構造函數,但只是作為基類的構造函數的傳遞; 沒有實際的代碼。

public ref class TestTempFloat : TestTemp<float>
{
    TestTempFloat(float val) : TestTemp(val) { };
};

如果你有很多這些,你可以使用預處理器:

#define IMPLEMENT_TESTTEMP(namesuffix, type) \
public ref class TestTemp ## namesuffix : TestTemp<type> \
{ \
    TestTemp ## namesuffix(type val) : TestTemp(val) { }; \
};

IMPLEMENT_TESTTEMP(Float, float)
IMPLEMENT_TESTTEMP(Double, double)
IMPLEMENT_TESTTEMP(Int, int)

如您所見,托管模板無法在它們所在的程序集之外訪問。 基本上,我們的想法是將托管模板公開為可以跨程序集邊界發送的通用接口。

所以在你的情況下,你會想要創建一個ITestTemp ,就像這樣......

generic<typename T> public interface class ITestTemp
{
  public:
    TestTemp(T val);
}

這是您將跨程序集導出的接口。 現在,您必須將托管模板轉換為該通用接口才能執行此操作,您可以使用繼承,具有以下簽名(為簡單起見,省略內部)

templace<typename T> ref class TestTemp : ITestTemp<T>

一旦你擁有它,你將不得不做“編譯器的工作”(通常只是為常規C ++模板自動處理),以便它可以在兩者之間進行轉換。 因此,您必須創建一個工廠方法,該方法將創建您要查找的特定實例。 它看起來像這樣

public ref class TestTempFactory
{
  public:
    generic<typename T> static ITestTemp<T>^ Create()
    {
      if (T::typeid == String::typeid)
      { return (ITestTemp<T>^) gcnew TestTemp<String>(); }
      //more cases as needed...
    }
}

如果不讓我知道的話,我希望能夠解釋得很清楚。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM