2011-01-21 12 views
5

sto progettando di fare un'interfaccia plug-in C++ ala How to create some class from dll(constructor in dll)?(с++) ma le preoccupazioni sono state sollevate che, se l'interfaccia viene utilizzata per creare DLL tramite MinGW o Borland e il caricatore DLL viene compilata con MSVC++, ci potrebbe essere i problemi. Poiché l'unica funzione esportata è dichiarata extern "C", non riesco a capire perché non funzionerebbe?C++ interfaccia DLL plug

Idee?

risposta

10

Se si desidera essere compatibili tra compilatori (e Rilascio/Debug) e utilizzare C++, è necessario un piccolo sforzo in più.

Fondamentalmente, è possibile passare i tipi di dati di base e puntare a classi virtuali pure. Queste classi non devono contenere alcun membro di dati, il loro distruttore non deve essere pubblico e non dovrebbero avere funzioni sovraccaricate.

La memoria non deve essere allocata in una DLL e rilasciata in un'altra. Ciò significa che non ci sono eccezioni e che è necessario un qualche tipo di conteggio dei riferimenti o meccanismo di restituzione.

Tutti i metodi all'interno della pura classe virtuale (ovvero "Interfaccia") devono essere contrassegnati con una convenzione di chiamata (preferirei stdcall).

Anche i cast dinamici non sono possibili, quindi è necessario disporre di alcune funzionalità in tutte le interfacce per eseguire il trucco (come QueryInterface in COM).

Questo funziona perché la maggior parte del compilatore su win32 cerca di essere compatibile con COM e risolve gli stessi problemi in un modo compatibile con COM. Per ottenere la prima interfaccia, è necessaria una semplice funzione C esportata dalla dll.

Se si utilizzano solo funzioni C e tipi di dati C, anche tutto funzionerà. Ma allora sei limitato a C senza l'ereditarietà delle classi &.

Spero che questo aiuti.


mutilazione dei nomi non è un problema:

prima: se si utilizzano le funzioni C con tipi di dati C, tutto è definito, non c'è nessun nome mangling (eccezione: in VS con STDCALL, è necessario rimappare il nome del nome "normale" C tramite la direttiva Linker)

2: I metodi all'interno delle classi non vengono esportati e quindi non vengono alterati. Chiami metodi tramite puntatore a classi virtuali pure (dette anche "Interfacce"). Questo usa un offset e nessun nome. Non è ancora possibile utilizzare il distruttore, poiché la posizione del distruttore all'interno del vtbl non è corretta per quanto ne so.


Se passate le strutture per funzioni/metodi, assicurarsi di correggere l'allineamento. Non è definito tra diversi compilatori.

+0

E riguardo il nome mangling? Sarà lo stesso per il distruttore in diversi compilatori? – ssmir

+0

Ciò significa che non è possibile utilizzare un plug-in realizzato con un compilatore diverso perché il simbolo per il vtable può essere diverso e anche gli offset del metodo possono essere diversi? – ssmir

+0

Ma la struttura vtable non è definita dallo standard C++? Quindi non dovrebbe essere un problema utilizzare un compilatore diverso (conforme). – Robert

0

Un'idea potrebbe utilizzare la funzione standard esterna C per creare un ClassFactory. Avere una certa convinzione su un punto di ingresso fisso (o più) che la DLL deve esporre per essere un plugin valido.

+0

Sì, l'unica funzione esportata sarebbe un extern "C" Plugin * GetPluginObject(). L'ho fatto prima, ma poi ho avuto il controllo delle DLL (cioè non lasciando che MinGW/Borland ecc. Nell'equazione) – Robert

+0

E se il tuo GetPluginObject restituisse un'istanza di qualche classe derivata da qualche * pura * classe virtuale, aren è compatibile VTable tra diverse implementazioni del compilatore? Penso che MS COM sfrutti queste idee ... –

+0

sono, in qualche modo. Vedi la mia risposta sopra. –