2012-09-21 14 views
7

Hola Estoy usando una biblioteca que ha anulado globalmente nuevo/eliminar. Pero tengo un problema con esta biblioteca, el problema es que debe inicializarse manualmente en la función principal.Ignorar globalmente anulado nuevo/eliminar

Ahora estoy tratando de usar otra biblioteca que inicialice algunas funciones antes de que se llame a main, desafortunadamente esta biblioteca usa las nuevas dentro de estas funciones. Así que recibo errores porque el administrador de memoria que usa las palabras clave nuevas/eliminadas anuladas aún no se han inicializado.

Me gustaría utilizar el administrador de memoria predeterminado porque quiero agregar pruebas de unidad a esta biblioteca. No tendría mucho sentido utilizar la memoria utilizada en la biblioteca que quiero probar, también utilizada por mi biblioteca de pruebas de unidad.

Entonces, ¿mi pregunta es si es posible ignorar globalmente anulado nuevo/eliminar cuando se incluye la segunda biblioteca y simplemente usar el nuevo/eliminar predeterminado?

Estoy usando visual studio 2010 en Windows 7 con el compilador C++ estándar.

+0

La respuesta dependerá de la plataforma y/o compilador. – atzz

+0

¿Desarrollas ambas bibliotecas o son de terceros? Si tiene el control del código de administración de memoria, me desviaría de anular el nuevo/eliminar y crear un * objeto de gestión de memoria * en el estilo de 'std :: tr1 :: shared_ptr'. – count0

+0

@ count0 Desarrollamos la biblioteca de Memory Manager. Es un administrador de memoria personalizado con un recolector de basura altamente optimizado. Y estoy tratando de usar las bibliotecas de prueba de refuerzo para las pruebas unitarias. – ProgrammerAtWork

Respuesta

0

¿Se puede colocar la inicialización del administrador de memoria principal en una biblioteca compartida?

Si esto es posible, puede intentar forzar la orden de inicialización de sus bibliotecas (por dependencia) para cargar (e inicializar) el administrador de memoria antes de cargar cualquier otra cosa. Sin embargo, esta es una solución muy frágil (o específica), ya que dependerá de las soluciones temporales específicas de la plataforma para forzar el orden en el que se inicializan las bibliotecas compartidas.

+0

Las palabras clave reemplazadas se escriben en el archivo de encabezado, por lo que no puedo ubicarlo realmente en otra biblioteca, y me gustaría usar el administrador de memoria predeterminado porque quiero agregar pruebas de unidad a esta biblioteca. No tendría mucho sentido utilizar la memoria utilizada en la biblioteca que quiero probar, también utilizada por mi biblioteca de pruebas de unidad. – ProgrammerAtWork

+0

Oh, forzar el orden de inicialización con dependencias podría funcionar, no sé ... pero todavía quiero usar el nuevo/eliminar predeterminado, así que puedo agregar pruebas unitarias a la biblioteca sin que las pruebas de la unidad se cuelguen si alguien mete la pata. – ProgrammerAtWork

+0

De tu pregunta parecía que solo tenías un problema al usar :: new y :: delete antes de que se inicie la gestión de la memoria. Si desea utilizar ambos, tendrá que llamar explícitamente al nuevo/eliminar que desea probar. Si los diseñadores de la biblioteca no usan un espacio de nombres para eso, podría estar en problemas, ya que no sabe qué método llaman internamente en su biblioteca. – count0

0

si anulando se realiza con una macro puede usar

#pragma push_macro ("new") 
#undef new 
...code with standard new here ... 
#pragma pop_macro ("new") 

Si se hace realmente por anulación de funciones, entonces puede construir temporalmente un "nuevo" macro mismo que llama a una función con otro nombre colocado en otro lugar, que simplemente llama a la función estándar. Las macros se resuelven antes de las llamadas a funciones.

1

No creo que esto sea posible sin modificar la biblioteca en sí. Supongo que se trata de una biblioteca estática (dentro de un dll, el nuevo/eliminar reemplazado será señalado por las funciones dentro del dll.)

Puede eliminar un archivo obj de una biblioteca estática mediante el comando (comando Visual prompt):

LIB /REMOVE:obj_to_remove /OUT:removed.lib input.lib 

para averiguar qué obj a eliminar, la primera carrera:

DUMPBIN /ARCHIVEMEMBERS input.lib 

verá líneas como

Archive member name at 14286: /0 compilation.dir\objfile1.obj 

14286 'identifica' el archivo obj. Para ver dónde está cada símbolo, ejecute:

DUMPBIN /LINKERMEMBER:1 input.lib > members.txt 

y busque la nueva/eliminar. members.txt contendrá los nombres destrozados de cada símbolo y un identificador del obj en el que se encuentra este símbolo. Por ejemplo

14286 [email protected][email protected]@[email protected]@2HB 

El 14286 le está diciendo al obj 'identificador' en la que se encuentra el símbolo.Si tiene problemas para encontrar nuevos/borrar, puede ejecutar:

DUMPBIN /SYMBOLS input.lib > sym.txt 

que echar al sym.txt los nombres alterados y unmangled para cada símbolo.

Al final, quitar el archivo obj con el comando LIB anteriormente reemplazando obj_to_remove por compilation.dir\objfile1.obj en nuestro ejemplo, y el enlace contra removed.lib.

Ahora, si no tiene suerte, otros símbolos que necesita pueden estar en el mismo archivo objeto que el nuevo/eliminar. En ese caso, se puede "cortar" la lib usando algo como this (por ejemplo el cambio de nombre new-dew y delete-nelete.)