簡體   English   中英

在 C++ 中定義需要在 C# 和 C++ 中實現的接口

[英]Define an interface in C++ that needs to be implemented in C# and C++

我有一個在 C++ 中定義的接口,現在需要在 C# 中實現。 解決這個問題的最佳方法是什么? 我根本不想在我的接口定義中使用 COM。 我現在解決這個問題的方法是有兩個接口定義,一個在 C++ 中,一個在 C# 中。 然后我將 C# 接口公開為 COM 服務器。 這是我用 C++ 編寫的應用程序,可以調用 C#。 無論如何,我可以避免必須在 C++ 和 C# 中定義我的實現嗎?

如果您願意將C ++ / CLI用於托管代碼而不是C#,那么您可以直接通過頭文件使用本機C ++接口定義。 這將是多么容易將取決於你的界面中究竟是什么 - 最簡單的情況是你可以從C使用的東西。

查看Marcus Heege的專家C ++ / CLI:.NET for Visual C ++程序員 ,獲取有關在.NET中混合本機和托管C ++的大量有用信息。

Swig是一個很好的工具,可以用C#等其他語言包裝C ++類。

你為什么不想用COM?

這本來是我的建議。 COM interop對我來說非常好用,我在C#中使用了COM對象和接口(只需引用COM對象,並自動創建運行時可調用包裝器)。 類似地將C#類標記為“為COM互操作注冊”已經反過來了。

用C ++編寫接口並使用宏使它看起來像UNIX上的標准cpp頭文件,就像Windows上的IDL文件一樣(如果這不起作用,你總是可以編寫一個python / ruby​​腳本來從中生成IDL C ++頭文件)。

編譯IDL以生成類型庫。 使用TypeLib Importer生成C#的接口定義並在那里實現接口。

在IDL中編寫接口並使用工具將接口編譯為目標語言。 在研究與跨語言接口有關的CORBA時,您可能會發現這方面的指針。

/艾倫

另一種方法是使用'扁平',C風格的API。 你也可以使用extern "C"來防止意外超載。 使用DEF文件顯式命名導出的函數,因此它們絕對不會以任何方式進行修飾(C ++函數在導出表中使用參數類型的編碼進行“修飾”)。

在x86上,注意調用約定。 它可能是明確聲明使用__stdcall__cdecl 因為P / Invoke主要用於調用Windows API,所以默認為StdCall,但C和C ++默認為cdecl,因為它支持varargs。

我最近將COM接口IRapiStream在一個扁平的C接口中,因為.NET似乎試圖將IStream轉換為一個存儲器,它因錯誤STG_E_UNIMPLEMENTEDFUNCTION而失敗。

你沒有提到你正在使用哪個版本的.NET,但是在使用Visual Studio .NET 2003時對我有用的東西是為真正的C ++類的疙瘩實現提供一個瘦C#包裝器:

public __gc class MyClass_Net {
public:
   MyClass_Net()
      :native_ptr_(new MyClass())
   {
   }
   ~MyClass_Net()
   {
      delete native_ptr_;
   }

private:
   MyClass __nogc *native_ptr_;
};

顯然,人們更喜歡在那里使用Boost shared_ptr,但是我永遠無法讓它們與V.NET 2003很好地配合使用......

方法只需通過指針轉發到底層的C ++方法。 可能必須轉換方法參數。 例如,要調用帶有字符串的C ++方法,C#方法應該采用System.String(Managed C ++中的System :: String)。 你必須使用System :: Runtime :: InteropServices :: Marshal :: StringToHGlobalAnsi()來做到這一點。

這種方法的一個好處是因為托管C ++是一種.NET語言,您可以將訪問器公開為屬性(__property)。 您甚至可以公開屬性,就像在C#中一樣。

暫無
暫無

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

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