Domanda

In C ++, la libreria statica A è collegata nelle librerie dinamiche B e C. Se una classe, Foo, è usata in A che è definita in B, C collegherà se non usa Foo?

Pensavo che la risposta fosse sì, ma ora sto incontrando un problema con xlc_r7 in cui la libreria C dice che Foo è un simbolo indefinito, per quanto riguarda C. Il mio problema è che la libreria C non sta usando la classe a cui fa riferimento. Questo collega in Win32 (VC6) e OpenVMS.

È una discrepanza del linker o un PBCAK?

Nuove informazioni:

  1. B dipende da C, ma non viceversa.

  2. Non sto usando / OPT: REF per il collegamento su Windows e si collega senza problemi.

È stato utile?

Soluzione

Quando si collega staticamente, due moduli diventano uno. Quindi, quando si compila C e si collega A in esso, è come se si fosse copiato tutto il codice sorgente di A nel codice sorgente di C, quindi compilato il codice sorgente combinato. Quindi C.dll include A, che ha una dipendenza da B tramite Foo. Dovrai collegare C alla libreria di collegamenti B per soddisfare tale dipendenza.

Nota che, secondo le tue informazioni, ciò creerà una dipendenza circolare tra B e C.

Altri suggerimenti

Sembra che sia probabilmente il linker (ld / unix), poiché (la maggior parte delle versioni che ho usato) collega le librerie da sinistra a destra - e se c'è un riferimento nel primo che è richiesto da in seguito il solito trucco è quello di aggiungere la prima libreria (o qualsiasi libreria richiesta) alla fine del comando.

Provalo e vedi ....

La tua linea di collegamento per C include la libreria di esportazione per B? In tal caso, come suggerisce Richard, sembra una cosa ordinante.

Un altro suggerimento è vedere se esiste un'opzione linker per ignorare i simboli non referenziati, se C non ha bisogno di quella funzionalità di A. Per il linker Microsoft questo è stato ottenuto con l'opzione / OPT: REF.

L'unico motivo per cui C non si collega è che il compilatore pensa che non abbia bisogno del simbolo Foo.

Poiché C non fa riferimento ai simboli Foo, ci deve essere un'altra ragione per cui il linker ha bisogno del simbolo.

L'unica altra ragione che conosco è un'esportazione di qualche tipo. Conosco solo Visual C ++, quindi ti suggerisco di cercare qualche equivalente di __declspec (dllexport) nei file preelaborati e vedere cosa lo genera.

Ecco cosa farei: avere l'output del preprocessore memorizzato in un file separato e cercare le occorrenze di Foo. O si verificherà come esportazione o è stato fatto riferimento in qualche modo dal compilatore.

Se la definizione di una particolare funzione non è richiesta, quella libreria non sarà collegata durante la fase di collegamento. Nel tuo caso, poiché la definizione di foo è presente nella libreria B e non nella libreria C. Pertanto, la libreria C non verrà caricata in memoria durante il caricamento dell'eseguibile.

Ma sembra che tu stia usando anche la funzione foo () nella libreria C, a causa della quale stai ottenendo l'errore corrispondente.

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