Pregunta

En C ++, la biblioteca estática A está vinculada a las bibliotecas dinámicas B y C. Si una clase, Foo, se usa en A, que está definida en B, ¿C se vinculará si no usa Foo?

Pensé que la respuesta era sí, pero ahora tengo un problema con xlc_r7 donde la biblioteca C dice que Foo es un símbolo indefinido, que es lo que se refiere a C. Mi problema con eso es que la Biblioteca C no está usando la clase que hace referencia a ella. Esto enlaza en Win32 (VC6) y OpenVMS.

¿Es esta una discrepancia del vinculador o un PBCAK?

Nueva información:

  1. B depende de C, pero no viceversa.

  2. No estoy usando / OPT: REF para vincular en Windows y enlaza sin problemas.

¿Fue útil?

Solución

Cuando se vincula estáticamente, dos módulos se convierten en uno. Entonces, cuando compila C y vincula A en él, es como si hubiera copiado todo el código fuente de A en el código fuente de C, luego compiló la fuente combinada. Así que C.dll incluye A, que depende de B a través de Foo. Deberá vincular la biblioteca de enlaces de C a B para satisfacer esa dependencia.

Tenga en cuenta que de acuerdo con su información, esto creará una dependencia circular entre B y C.

Otros consejos

Parece que es probablemente el vinculador (ld / unix), ya que (la mayoría de las versiones que he usado) ld vincula las bibliotecas de izquierda a derecha, y si hay una referencia en la primera que es requerida por una posterior, el truco habitual es agregar la primera biblioteca (o cualquier biblioteca requerida) al final del comando.

Es un intento y ver ...

¿Su línea de enlace para C incluye la biblioteca de exportación para B? Si es así, como Richard sugiere, suena como una cosa de pedido.

Otra sugerencia es ver si hay una opción de vinculador para ignorar los símbolos no referenciados, si C no necesita esa funcionalidad de A. Para el vinculador de Microsoft esto se logró con el interruptor / OPT: REF.

La única razón por la que C no se vincula es que el compilador cree que necesita el símbolo Foo.

Dado que C no hace referencia a los símbolos Foo, tiene que haber otra razón por la cual el enlazador necesita el símbolo.

La única otra razón que conozco es una exportación de algún tipo. Solo conozco Visual C ++, por lo que sugiero que busques un equivalente de __declspec (dllexport) en los archivos preprocesados ??y veas lo que lo genera.

Esto es lo que haría: tener la salida del preprocesador almacenada en un archivo separado y buscarla en las incidencias de Foo. O bien se producirá como una exportación, o el compilador lo ha referenciado de alguna manera.

Si la definición de una función particular no es necesaria, entonces esa biblioteca no se vinculará durante la fase de enlace. En su caso, como la definición de foo está presente en la biblioteca B y no en la biblioteca C. Por lo tanto, la biblioteca C no se cargará en la memoria mientras se carga el archivo ejecutable.

Pero parece que también está utilizando la función foo () en la biblioteca C, debido a que está recibiendo el error correspondiente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top