Stai mischiando tre cose diverse.
In primis, non esiste un modo "standard" per creare dll - per il semplice fatto che lo standard C++ neanche menziona le dll. __declspec(dllexport) è il modo più semplice per esportare classi e quant'altro usando VC++, l'alternativa è passare al linker un file .def, il che può essere utile per esportare giusto funzioni "in stile C" con nomi non decorati.
E qui veniamo alla questione del codice indipendente dal compilatore; dato che il C++ di suo non ha un ABI stabile (almeno, non su Windows con VC++), ci sono sostanzialmente due modi per ottenere l'effetto che chiedi: usare COM (complicato) o esportare solo funzioni in stile C, non passando mai oggetti C++ oltre il confine della dll, ma sempre handle/puntatori di qualche genere (può essere un'idea usare l'idioma PIMPL).
Sulla questione Linux: ovviamente dovrai ricompilare (a meno di non voler usare Wine); per il resto, se non ricordo male di default quando crei una shared dynamic library con gcc su Linux tutti i simboli sono esportati di default, per cui non devi fare nulla di particolare. Su Linux la ABI di g++ mi pare sia ormai abbastanza fissata (usano la ABI C++ Itanium "adattata" a piattaforme x86), così come la ABI di libstdc++, per cui non dovrebbero esserci eccessivi problemi di compatibilità binaria in avanti, anche se è buona norma, se devi distribuire dei binari, compilarli con la minima versione di gcc e libstdc++ compatibile con le versioni attuali (tipicamente si compila sull'ultima Debian Stable o su una Fedora stabile); è sempre possibile comunque fare linking statico, ma a quel punto fai prima a linkare anche l'eseguibile insieme e fare un mega-eseguibile tutto in uno.