Domanda

Sto cercando di capire le mie opzioni per chiamare un'implementazione della biblioteca C# da C ++ non gestito.

Il mio modulo di alto livello è un DLL C ++ COM/ATL non gestito. Vorrei integrare la funzionalità di un C# DLL gestito esistente. Ho e posso ricompilare la fonte per entrambe le librerie.

Capisco dalla lettura di articoli come Questa panoramica su msdn e Questo è così domanda Che potrebbe essere possibile creare una DLL "in modalità mista" che consente al codice C ++ nativo di chiamare nella libreria C#.

Ho un paio di domande su questo approccio:

  1. Come posso impostare questo? Posso semplicemente cambiare alcune proprietà sul progetto COM/ATL esistente per consentire l'uso dei moduli C#?
  2. In che modo queste chiamate in modalità mista differiranno nelle prestazioni dalle chiamate interop? Esiste un formato di stringa comune che può essere utilizzato per prevenire la conversione o copie profonde tra i moduli?
  3. Se questa DLL viene creata in modalità mista, può comunque essere interfacciata/utilizzata allo stesso modo dai suoi client COM o deve essere a conoscenza della modalità miscelata?
  4. L'inclusione del CLR imporrà un sovraccarico sostanziale quando si carica questo oggetto COM?

Sono nuovo nello sviluppo di Windows, quindi si prega di commentare se non altro nella dichiarazione delle domande necessita di chiarimenti o correzioni.

Grazie in anticipo.

È stato utile?

Soluzione

Come posso impostare questo? Posso semplicemente cambiare alcune proprietà sul progetto COM/ATL esistente per consentire l'uso dei moduli C#?

Se controlli completamente quel progetto, quindi modificare tali impostazioni non è un problema, allora sicuro. Tutto ciò di cui hai bisogno è abilitare /clr Per questo progetto (nelle proprietà del progetto, apri la pagina "generale" e cerca il supporto "Runtime del linguaggio comune"). Ora puoi usare le maniglie gestite (^) e altri bit C ++/CLI nel tuo progetto, se necessario. Tutto il codice esistente scritto in semplice C ++ dovrebbe semplicemente continuare a funzionare (ora verrà compilato su MSIL, in quanto il più possibile, ma la sua semantica rimarrà invariata).

In che modo queste chiamate in modalità mista differiranno nelle prestazioni dalle chiamate interop? Esiste un formato di stringa comune che può essere utilizzato per prevenire la conversione o copie profonde tra i moduli?

Una chiamata in modalità mista sarà più veloce, perché utilizza convenzioni di chiamata più veloci e non fa alcun marshalling nel modo in cui si interroga COM (usi tipi intrinsecamente compatibili o fai le tue conversioni esplicite).

Non esiste un formato di stringa comune - il problema è quello System::String Entrambi assegnavano e possiede il suo buffer e richiede anche che sia immutabile; Quindi non puoi creare un buffer da solo e poi avvolgerlo come String, o creare un String e quindi usalo come buffer per output Testo.

Se questa DLL viene creata in modalità mista, può comunque essere interfacciata/utilizzata allo stesso modo dai suoi client COM o deve essere a conoscenza della modalità miscelata?

Può essere interfacciato allo stesso modo, ma se viene inserito tramite un punto di ingresso nativo, proverà a caricare il CLR nel processo, a meno che uno non sia già caricato. Se il client chiamante aveva già caricato CLR prima della chiamata (o il client era stesso chiamato dal codice gestito), otterrai il CLR che è già caricato, il che potrebbe essere diverso dal CLR richiesto dal codice (EG Client potrebbe aver caricato 1.1 e il codice necessita di 2.0).

L'inclusione del CLR imporrà un sovraccarico sostanziale quando si carica questo oggetto COM?

Dipende da ciò che definisci in base all'alto. Dimensione del codice? Runtime Penalties? Impronta di memoria?

In ogni caso, il caricamento del CLR significa che ottieni tutti i macchinari GC e JIT. Quelli non sono economici. Detto questo, se devi chiamare il codice gestito in definitiva, non c'è modo di aggirare questo - lo farai avere Per caricare CLR in qualche processo per farlo. Le sanzioni non differiranno tra i gruppi COM COM e in modalità mista/CLI.

Altri suggerimenti

Non posso dire molto sui dettagli come EG i problemi di stringa, dal momento che non ho mai usato attivamente questo approccio.

Ma puoi facilmente consumare qualsiasi interfaccia COM da qualsiasi codice C# semplicemente lasciando che una procedura guidata VS crei un proxy per te, non vi è alcun sovraccarico di prestazioni tranne quella che hai sempre quando invocano COM e .NET.

La direzione opposta, devi solo impostare i tuoi gruppi C# ComVisibleAttribute Per vero (in vs è una semplice casella di controllo nelle proprietà del progetto), quindi il compilatore creerà automaticamente interfacce COM per te. Ancora una volta, non esiste una penalità di performance aggiuntiva.

Hth!

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