Domanda

Devo rendere disponibile una grande libreria c ++ per l'uso in linguaggi .Net come C #.

La libreria contiene un gran numero di classi che possono essere suddivise in due gruppi. Le classi contate da Refrence, che implementano la classe astratta IRefCounted e usano un metodo factory per crearle, e solo classi semplici usando new / delete.

Nella pubblicità ci sono molte semplici funzioni.

Originariamente stavo per scrivere classi wrapper per tutto in c ++ / clr. Tuttavia, si desidera che le librerie wrapper risultanti funzionino su Mono. Ricompilare la libreria e il wrapper per indirizzare ogni piattaforma va bene, tuttavia il problema è che sembra che c ++ / clr possa targetizzare solo Windows poiché non esiste un compilatore per indirizzare altre piattaforme e quindi il codice wrapper non funzionerà su altre forme. ..

C'è qualcosa che mi è mancato qui (come un howto per eseguire c ++ / clr su x platform guide) o c'è un modo alterativo per rendere tutte le funzioni, le strutture e le classi c ++ disponibili in C #?

MODIFICA: Per disponibilità intendo disponibile per l'uso, ad esempio dire nella mia libreria c ++ che avevo

//namespace maths{
class Vector2
{
public:
    float x,y;
    Vector2();
    Vector2(const Vector&);
    Vector2(float x, float y);
    float Dot();
    //operators
    ...
};

Quindi in C # id piace essere in grado di usarlo come una normale classe, ad esempio

maths::Vector2 a = new maths::Vector2(5, 5);
maths::Vector2 b = new maths::Vector2(1, 10);
b *= 3
maths::Vector2 c = a + b;
//c.x == 8, c.y == 35

Inoltre, comunque, non posso modificare la libreria c ++, tutto deve essere fatto come un wrapper per le classi e le funzioni esistenti.

È stato utile?

Soluzione

I wrapper C ++ / CLI sono sicuramente l'opzione migliore se stai prendendo di mira solo Windows. Si comportano molto bene, sono molto facili da scrivere e mantenere, ecc. Ma, come hai detto, questo non funzionerà su Mono. Il problema è che l'assembly che viene creato non è un clr: pure assembly, ma uno che ha un codice nativo e IL misto, quindi non funzionerà al di fuori di Windows. Inoltre, è necessario creare assiemi separati in C ++ / CLI per target x86 e x64, se si intende utilizzare sistemi a 64 bit.

SWIG è sicuramente un'opzione. Può gestire tutte le complessità del wrapping di una classe C ++, ma quando si arriva a problemi più complessi, in genere è necessario apportare alcune modifiche.

Consiglio di visitare il sito principale SWIG , e in particolare il loro sezione C #.

Per buoni esempi dell'uso di SWIG per avvolgere una libreria molto complessa, consulta OGRE Dot Net (quasi morto, ma comunque un buon esempio) o GDAL . Da quello che ricordo, entrambi hanno una gestione speciale per le caratteristiche specifiche di C # e gestiscono classi, enumerazioni di riferimento, ecc.

L'altra cosa bella di SWIG: se crei involucri SWIG, è molto facile estenderlo ad altre lingue se ne hai bisogno. Una volta che hai i wrapper, creare involucri Java, python, ruby, ecc è facile.

Altri suggerimenti

Ho usato SWIG per racchiudere il codice C ++ e chiamarlo da mono ha funzionato alla grande.

Se rendendoti disponibile intendi rendere disponibile per la modifica, potresti implementare un sistema di riflessione basato su modello / macro in C ++ e costruire il wrapper per C # e Mono. Per un'idea su come implementarlo, puoi dare un'occhiata a

  

DECLARE_DYNAMIC

e

  

RUNTIME_CLASS

macro in MFC e

  

ICustomTypeDescriptor

interfaccia in C #.

Alcuni libri della serie Game Programming Gems trattano anche questo argomento.

Se invece intendi renderlo disponibile per la programmazione, dovrai obbedientemente fornire al programmatore tutti i tipi con cui dovrebbe lavorare, cioè devi avvolgerli.

Per quanto ne so, Mono è una macchina virtuale in grado di eseguire il codice byte prodotto dal CLR (e altri), quindi i binari C # sono tutto ciò che serve.

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