Domanda

Ho un'interfaccia che ho definito in C++ che ora deve essere implementata in C#.Qual è il modo migliore per farlo?Non voglio affatto usare COM nella mia definizione di interfaccia.Il modo in cui ho risolto questo problema adesso è avere due definizioni di interfaccia, una in C++ e una in C#.Quindi espongo le interfacce C# come server COM.Questa era la mia applicazione scritta in C++ che può chiamare in C#.Esiste comunque un modo per evitare di dover definire la mia implementazione in C++ e C#?

È stato utile?

Soluzione

Se desideri utilizzare C++/CLI per il codice gestito anziché C#, puoi semplicemente utilizzare la definizione dell'interfaccia C++ nativa direttamente tramite il file di intestazione.Quanto sarà facile dipenderà esattamente da cosa c'è nella tua interfaccia: il caso più semplice è qualcosa che potresti usare da C.

Dai un'occhiata a Marcus Heege Esperto C++/CLI:.NET per programmatori Visual C++, per molte informazioni utili sulla combinazione di C++ nativo e gestito in .NET.

Altri suggerimenti

Sorseggia è un ottimo strumento per racchiudere le classi C++ in altri linguaggi come C#.

Perché non vuoi usare COM?

Questo sarebbe stato il mio suggerimento.L'interoperabilità COM ha funzionato molto bene per me e ho utilizzato oggetti e interfacce COM in C# (è sufficiente fare riferimento all'oggetto COM e il wrapper richiamabile in runtime viene creato automaticamente).Allo stesso modo, contrassegnare una classe C# come "Registro per l'interoperabilità COM" ha funzionato al contrario.

Scrivi l'interfaccia in C++ e usa le macro per farla sembrare un file di intestazione cpp standard su UNIX e come un file IDL su Windows (se questo non funziona, puoi sempre scrivere uno script python/ruby per generare l'IDL dal file di intestazione C++).

Compila l'IDL per generare una libreria dei tipi.Utilizzare TypeLib Importer per generare le definizioni di interfaccia per C# e implementare le interfacce lì.

Scrivi l'interfaccia in IDL e utilizza uno strumento per compilare l'interfaccia nella lingua di destinazione.Potresti trovare indicazioni a questo riguardo esaminando CORBA che riguardava l'interfaccia tra lingue diverse.

/Allan

L'altro approccio consiste nell'utilizzare un'API "piatta" in stile C.Potresti anche usare extern "C" per evitare sovraccarichi accidentali.Utilizzare un file DEF per denominare esplicitamente le funzioni esportate, in modo che non siano sicuramente decorate in alcun modo (le funzioni C++ sono "decorate" con una codifica dei tipi di parametri nella tabella di esportazione).

Su x86, fai attenzione alle convenzioni di chiamata.Probabilmente è per dichiarare esplicitamente l'uso di __stdcall O __cdecl.Poiché P/Invoke viene utilizzato principalmente per richiamare le API di Windows, per impostazione predefinita è StdCall, ma C e C++ per impostazione predefinita cdecl, poiché supporta varargs.

Recentemente ho avvolto l'interfaccia COM IRapiStream in un'interfaccia C flat poiché .NET sembrava tentare di convertire IStream in un archivio, cosa che non è riuscita con l'errore STG_E_UNIMPLEMENTEDFUNCTION.

Non dici quale versione di .NET stai utilizzando, ma qualcosa che ha funzionato per me nell'uso di Visual Studio .NET 2003 è fornire un sottile wrapper C# attorno all'implementazione punteggiata della vera classe C++:

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

private:
   MyClass __nogc *native_ptr_;
};

Ovviamente, si preferirebbe usare un Boost shared_ptr lì, ma non sono mai riuscito a farli funzionare bene con V.NET 2003...

I metodi inoltrano semplicemente ai metodi C++ sottostanti tramite il puntatore.Potrebbe essere necessario convertire gli argomenti del metodo.Ad esempio, per chiamare un metodo C++ che accetta una stringa, il metodo C# dovrebbe probabilmente accettare un System.String (System::String in Managed C++).Dovresti utilizzare System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi() per farlo.

Un aspetto interessante di questo approccio è che, poiché Managed C++ è un linguaggio .NET, è possibile esporre le funzioni di accesso come proprietà (__property).Puoi anche esporre gli attributi, proprio come in C#.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top