2012-03-02 6 views
6

Ho due progetti in una soluzione di Visual Studio. Uno costruisce un LIB statico, l'altro costruisce una DLL dinamica. Entrambi usano il collegamento di runtime statico (/ MT e/MTd), ed entrambi usano Boost. Boost non era una mia decisione, volevo buttarlo fuori ma sono stato respinto dal comitato."Mescolare una libreria di boost con un runtime statico è una pessima idea ..."

LIB crea correttamente, ma la DLL tosse un errore da auto_link.hpp (riga 354): "Mescolare una libreria di boost di DLL con un runtime statico è una pessima idea ...".

#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) 
# define BOOST_LIB_PREFIX 
#elif defined(BOOST_DYN_LINK) 
# error "Mixing a dll boost library with a static runtime is a really bad idea..." 
#else 
# define BOOST_LIB_PREFIX "lib" 
#endif 

Non ho definito BOOST_DYN_LINK. Sembra che Boost stia facendo un salto che dal momento che sto costruendo una DLL (_USRDLL e _WINDLL sono definiti), voglio il collegamento dinamico al runtime (/ MD o/MDd, che definisce _DLL) o il collegamento DLL contro Boost. Questo non è corretto in quanto ho chiesto specificamente per il collegamento statico (/ MT o/MTd).

Ho archiviato uno bug report contro Boost per le sue ipotesi errate, ma questo non mi aiuta con l'utilizzo della libreria. Nel report, i manutentori Boost insistono sul fatto che lo sto impostando (nonostante il fatto che un audit abbia dimostrato che non lo sono, e Boost lo manipola in almeno 30 file). Ho trovato one answer nella mailing list di Boost, che in sostanza afferma di cambiare le impostazioni del mio progetto per accogliere Boost.

Il passaggio a Dynamic Runtime Linking (/ MD e/MDd) non è possibile poiché il collegamento statico è stato scelto (1) a causa di considerazioni di sicurezza e (2) un'altra libreria utilizza il collegamento statico. Questo non è negoziabile, non abbiamo scelta.

Per riepilogare per chiarezza (TLDR): Voglio utilizzare il collegamento statico per tutto, mentre il mio programma di output è una DLL (non una LIB statica, non un EXE). Tutto è collegato staticamente alla DLL.

Qualcuno sa come utilizzare questa libreria su Windows per creare una DLL con collegamento statico?

+0

È sufficiente rimuovere il controllo offendente da auto_link.hpp? O #undef _USRDLL e _WINDLL prima che auto_link.hpp sia incluso e poi ridefinirli in seguito? –

+0

Ho appena avuto a che fare con questo un paio di settimane fa, anche se non riesco a ricordare i dettagli in cima alla mia testa. Abbiamo una DLL costruita contro CRT statico e boost statico e non ci sono errori/avvertenze. Lo controllerò domani se nessuno risponde da allora. – Luke

+7

Si noti che * è estremamente pericoloso * creare una DLL che si collega staticamente alla libreria di runtime C. Ciò significa che la memoria allocata in una DLL non può essere direttamente liberata in un'altra. Questo potrebbe sembrare che non accadrà, ma può. E otterrai crash casuali da esso. –

risposta

9

Questo problema è davvero un difetto con le impostazioni di boost. Per qualche motivo sconosciuto (che non riesco a determinare per essere logico - in quanto non ha effetto). Boost Python sarà forzare il collegamento dinamico di boost, indipendentemente dalle opzioni utente

In breve, se si ha boost-python nel progetto, boost in modo errato impedisce il collegamento statico di boost con l'opzione/MT.

Questo problema viene risolto facilmente definendo BOOST_PYTHON_STATIC_LIB prima di includere le intestazioni boost.

+1

Lo accetterò per aiutare i futuri visitatori perché sembra una risposta ragionevole. Ma un avvertimento ai futuri visitatori: non ero in grado di testarlo. – jww

+0

Puoi essere specifico su cosa intendi per definizione di BOOST_PYTHON_STATIC_LIB. Il percorso assoluto per la biblioteca? Sto avendo questo errore e non riesco a romperlo. Solo una riga di codice di esempio? – bw4sz

+0

@ bw4sz, Prima di includere l'intestazione di potenziamento #define BOOST_PYTHON_STATIC_LIB, o impostarlo come definizione del preprocessore nel tuo IDE/Makefile –

30

Versione corta: ascolta i ragazzi sul Boost ML. Boost non supporta ciò che stai cercando di fare, ed è comunque una cattiva idea. Meglio accettarlo e fare in modo che l'altra libreria utilizzi il runtime dinamico.

versione più lunga:

Sembra che tu stia fraintendendo quello Boost che si sta dicendo. Stai cercando di analizzare attraverso il codice sorgente Boost invece di leggere quello che sta dicendo:

auto_link.hpp (linea 354): "Mixing una libreria DLL spinta con un runtime statica è una pessima idea .. . ".

Boost pensa che si sta costruendo una DLL, mentre allo stesso tempo il collegamento staticamente alle librerie di runtime. Che è esattamente quello che stai facendo; Boost ha rilevato con precisione ciò che stai cercando di fare.

Il tuo problema è che la libreria Boost non supporta in una DLL che non si collega dinamicamente alle librerie di runtime. Il motivo è che è "una pessima idea". Quindi controllano se stai cercando di farlo e fermano la tua build con un messaggio di errore che ti ricorda questo fatto.

I "freecards" su Boost che non sanno come far funzionare qualcosa "out of the box" lo impediscono perché il collegamento statico al runtime in una DLL di solito è un errore dell'utente. È fatto accidentalmente o per ignoranza dei principali problemi che questo può creare.

Se si collega staticamente ai runtime, ogni DLL/exe avrà una propria copia dei runtime, con le proprie variabili globali. E poiché l'heap viene gestito tramite globals, ciò significa che ogni DLL/exe avrà il proprio heap. Quindi, se provi a liberare memoria allocata in un altro spazio indirizzo ... boom. E questo è molto più facile di quanto pensi se non stai attento.

Ciò può causare altri problemi. I "frees" stanno cercando di impedirti di spararti ai piedi. Ma ovviamente sai meglio che "costringere i loro schifosi agli utenti onesti e ignari" che potrebbero voler essere avvisati quando stanno per attraversare una scogliera.

Ora, è sufficiente rimuovere il messaggio di errore. La maggior parte di Boost è intestazioni, quindi finché non si sta effettivamente collegando a uno qualsiasi dei suoi .libs, si dovrebbe andare bene. Comunque, direi che "auto_link.hpp" è usato solo dalle parti di Boost che sono .libs, le probabilità sono buone che il fatto che tu l'abbia incontrato per cominciare significa che stai cercando di collegarti a un Boost .lib.

Passaggio a dinamico Runtime Linking (/ MD e/MDD) non è fattibile in quanto il collegamento statico è stato scelto (1) per motivi di sicurezza, e (2) un altro libreria utilizza il collegamento statico.

Se la sicurezza è una considerazione, si dovrebbe essere consapevoli di questo: il fatto stesso che si sta costruendo una DLL significa che l'applicazione è potenzialmente aperto a iniezioni di DLL, a prescindere da come si collega ai tempi di esecuzione. Quindi non vedo come il collegamento dinamico sia meno sicuro di quello statico.

+1

Non penso che sia giusto. auto_link.hpp sta verificando _DLL che è definito in base a quale CRT stai collegando, non a quale tipo di progetto stai costruendo. boost viene fornito con versioni predefinite delle sue librerie che si collegano con il CRT statico; li usiamo in una DLL bene. Ovviamente non usiamo le classi boost nell'interfaccia della DLL per le ragioni che hai affermato. – Luke

+0

@Luke: non importa quali siano i #defines; l'errore che ottiene * esattamente * corrisponde a come dice che sta costruendo la sua DLL. Il messaggio di errore Boost sta dicendo che non può costruire una DLL in questo modo. –

+1

Ovviamente la definisce materia; questo è il significato del messaggio di errore. Sono d'accordo che alcune opzioni di configurazione non sono corrette da qualche parte, ma è possibile costruire nella configurazione descritta nella domanda originale. incrementa i binari delle navi in ​​più configurazioni, una delle quali è potenziata come una lib fisica che si collega al CRT statico. Lo colleghiamo in una DLL senza problemi. – Luke

Problemi correlati