[英]C++ Interop: How do I call a C# class from native C++, with the twist the class is non-static?
我有一個用本機C ++編寫的大型應用程序。 我還有一個C#課,我需要打電話。
如果C#類是靜態的,那么它將是微不足道的(Web上有很多例子) - 只需編寫混合的C ++ / CLI包裝器,導出接口,然后就完成了。
但是,C#類是非靜態的,並且不能更改為靜態,因為它有一個接口(如果您嘗試使C#類靜態,編譯器將生成錯誤)。
有沒有人遇到過這個問題 - 如何將非靜態C#類導出到本機C ++?
更新2010-11-09
最終的解決方案:嘗試COM,這很好用,但不支持結構。 所以,使用C ++ / CLI包裝器,因為我絕對需要能夠在C ++和C#之間傳遞結構。 我根據這里的代碼編寫了一個混合模式.dll包裝器:
由於目標類是非靜態的,我不得不使用單例模式來確保我只是實例化目標類的一個副本。 這確保了一切都足夠快,以滿足規格。
如果你想讓我發布一個演示項目,請聯系我(雖然,公平地說,我從C ++調用C#,而現在大多數人都希望從C#調用C ++)。
與靜態類一樣,C ++ / CLI或COM互操作也適用於非靜態類。 使用C ++ / CLI,您只需引用包含非靜態類的程序集,然后您可以使用gcnew
來獲取對新實例的引用。
是什么讓你認為這對你的非靜態課是不可能的?
編輯:有示例代碼在這里 。
using namespace System;
public ref class CSquare
{
private:
double sd;
public:
CSquare() : sd(0.00) {}
CSquare(double side) : sd(side) { }
~CSquare() { }
property double Side
{
double get() { return sd; }
void set(double s)
{
if( s <= 0 )
sd = 0.00;
else
sd = s;
}
}
property double Perimeter { double get() { return sd * 4; } }
property double Area { double get() { return sd * sd; } }
};
array<CSquare ^> ^ CreateSquares()
{
array<CSquare ^> ^ sqrs = gcnew array<CSquare ^>(5);
sqrs[0] = gcnew CSquare;
sqrs[0]->Side = 5.62;
sqrs[1] = gcnew CSquare;
sqrs[1]->Side = 770.448;
sqrs[2] = gcnew CSquare;
sqrs[2]->Side = 2442.08;
sqrs[3] = gcnew CSquare;
sqrs[3]->Side = 82.304;
sqrs[4] = gcnew CSquare;
sqrs[4]->Side = 640.1115;
return sqrs;
}
我想到了兩種選擇。
幾年前我已經調查了這個主題:我想使用原生代碼中的log4net和Npgsql庫,即使沒有/ clr密鑰也可以編譯。
Paul DiLascia在他的兩篇引人注目的文章中描述了這種技術背后的主要思想:
使用我們的ManWrap庫在Native C ++代碼中獲得最佳.NET
這個解決方案的主要思想是gcroot智能指針和intptr_t在內存中具有完全相同的表示。 我們創建了一個名為GCROOT(T)的宏,它在托管代碼中使用gcroot,在非托管代碼中使用intptr_t。 我們使用本機接口和托管實現創建DLL,並使用本機代碼中的dll。
我很容易為托管類創建一些適配器並在本機C ++世界中使用它們,即使沒有/ clr密鑰也可以編譯我的源代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.