Pregunta

Duplicar de la siguiente pregunta: C conflicto función


Hola, en mi proyecto actual que tengo que usar algún tipo de interfaz lib. Los nombres de las funciones son dadas por esta interfaz, lo que hacen es esto funciona desarrolladores elección. Por lo que yo puedo decir un proyecto deberá utilizar estas funciones, y cuando se trata de la compilación que elegir el lib y con ella la funcionalidad. Lo que trato de hacer es usar un lib existente y mi lib al mismo tiempo, envolviendo la otra y lo llaman en funciones mein:

otherlib:

int function1 (int a) {
// do something
}

mibiblioteca:

int function1 (int a) {
//my code here
    otherlib::function1(a);
}

El problema es que no tengo acceso a la otra y la otra lib lib no tiene ningún espacios de nombres. Ya he intentado

namespace old {
    #include "otherlib.h"
}

y luego llamar a la antigua función de edad :: function1 en mi función. Esto funciona siempre ya que es sólo archivo de cabecera. Las exportaciones lib que es símbolo de vuelta al espacio global. También algo así como

namespace new {
    function1 (int a) {
        ::function1(a);
    }
}

no funcionó. Por último, pero no menos lo intente IFDEFs y define sugirió aquí

pero no tuvo éxito.

Alguna idea de cómo resolver esto? Gracias de antemano.

EDIT:. Yo no tengo acceso a la antigua lib ni el proyecto de ambas bibliotecas se utilizan en

Edit2: al menos el viejo lib es una estática

¿Fue útil?

Solución

Los espacios de nombres en C resuelven usando nombres de bibliotecas de prefijos como:

libtal -> foo_function1
libbar -> bar_function1

Estos prefijos son espacios de nombres reales. por lo que si usted escribe libbar

int bar_function1(int a) {
     function1(a);
}

Esta es la manera de resolver los problemas.

C tiene espacios de nombres --- que sólo llamados prefijos;)

Otra opción es hacer varios trucos sucios con la carga dinámica de las bibliotecas como:

h1=dlopen("libfoo.so")
foo_function1=dlsym(h1,"function1")

h2=dlopen("libbar.so")
bar_function1=dlsym(h2,"function1")

Otros consejos

Parece como si el otro lib es C y su código es C ++. Puede estar ejecutando en un problema mangling (compiladores de C ++ mangle los símbolos - añadir material extra en el nombre del símbolo no diferenciar las sobrecargas y similares)

.

Si la biblioteca es pura C que puede probar:

extern "C" { // disable mangling of symbol names in the block
#include "otherlib.h"
}

namespace new_lib { // new is a reserved word
   int function1( int a ) {
      ::function1(a);
   }
}

Yo no lo he probado. También considerar la provisión de los mensajes de error que está recibiendo.

Otra opción sería (si la biblioteca es dinámica) cargar dinámicamente el lib y llamar a la función. En Linux (no sé acerca de las ventanas) que puede utilizar dlopen para abrir la biblioteca, dlsym para obtener el símbolo y lo llaman:

// off the top of my head, not tried:
int function1( int a )
{
   int (*f)(int); // define the function pointer
   void * handle = dlopen( "library.so" );
   f = dlsym( handle, "function1" );
   f( a ); // calls function1(a) in the dynamic library
}

En este caso, ya que no está vinculando con la librería no obtendrá un conflicto símbolo, pero de nuevo, sólo es válido para las bibliotecas dinámicas y es bastante engorroso para el uso regular.

Actualizar

Si los usuarios no utilizan 'otherlib' directamente (no incluirán sus cabeceras) y que será solamente C ++, entonces el primer enfoque podría ser posible (aunque sea horrible para leer):

// newlib.h
namespace hideout {
   int f( int a );
}
using namespace hideout; // usually I would not put this on the header

// newlib.cpp
extern "C" { // if otherlib is C, else remove this line
#include "otherlib.h"
}
namespace hideout {
   int f( int a ) { return ::f( a*2 ); }
}

// main.cpp
#include "newlib.h"
int main()
{
   std::cout << f( 5 ) << std::endl;
}

¿Cómo funciona? código de usuario sólo verá una declaración de function1 (en el ejemplo f ()), ya que no están incluidos los otherlib.h . Dentro de su unidad de compilación ves las dos declaraciones, pero a diferenciar a través del uso del espacio de nombres. La instrucción using en la cabecera no te molesta que haya calificado plenamente en su CPP. El usuario main.cpp incluirá sólo a su cabecera, por lo que el compilador sólo verá escondite :: f , y lo verá en cualquier lugar debido a la instrucción using. El enlazador no tendrá ningún problema como el símbolo C ++ se ha mezclado identificar el espacio de nombre real:

// g++ 4.0 in macosx:
00002dbe T __ZN7hideout9function1Ei // namespace hideout, function1 takes int, returns int
00002db0 T _function1

Si el código de usuario incluirá tanto la cabecera y otherlib.h , entonces tendrá que calificar qué función se quiere llamar.

Si usted está realmente desesperada, se podría escribir una biblioteca envoltorio que utiliza espacios de nombres o prefijos o permite el truco dlsym. tendría que estar vinculada de forma dinámica (para evitar conflictos de símbolos) Esta biblioteca envoltorio. La biblioteca dinámica podría entonces tener segura la antigua biblioteca estática incrustado en él. Sólo asegúrese de que no exporta los símbolos de la biblioteca estática al hacer la biblioteca envoltorio dinámico.

No se puede resolver este en tiempo de enlace, por lo que tendrá que resolver en tiempo de ejecución a través de las bibliotecas dinámicas. El símbolo para esas funciones se esencialmente al horno una vez que la biblioteca se ha generado. Si dos bibliotecas exportar el mismo símbolo, no pueden estar vinculadas tanto con estáticamente.

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