2010-01-06 5 views
6

Escribí una biblioteca de clases en C++ y la compilé con éxito en Linux con g ++ como objeto compartido, y luego creé algunas aplicaciones que la usaban. Ahora tengo que portarlo a VS2008. Di todas las clases los prefijos requeridos __declspec (dllexport), luego traté de compilarlo. Consigo un montón de advertencias, que básicamente tienen que ver con:problemas con portar una biblioteca de clases DLL C++ a Visual Studio

  1. mis clases de excepción personalizada, derivados de std :: runtime_error, que rendimiento: "advertencia C4275: clase no DLL-interfaz 'std :: runtime_error 'utilizado como base para la clase de interfaz dll' cci :: FileOperationException '". ¿Cómo se supone que voy a hacer una clase de biblioteca estándar dll-exportable?
  2. especificaciones de excepción en las declaraciones de las funciones miembro, que causan "advertencia C4290: especificación de excepción C++ ignorada excepto para indicar que una función no es __declspec (nothrow)". Leí en alguna parte que VS no los admite y que lo hace en otro lado. Qué muy confuso.

que leer a la gente diciendo que la exportación de clases en un archivo DLL es generalmente una mala idea, de que hay una gran cantidad de cosas que pueden salir mal, y ahora tengo la cabeza llena de conceptos como la incompatibilidad binaria, el infierno DLL, compilador la versión no coincide, etc., y para ser sincero, realmente no puedo entenderlo. Entonces, ¿cuál es la forma correcta, segura y fácil de crear una biblioteca de clases compartida en Windows?

Gracias.

+3

¿Realmente necesita ser una DLL? Hacer una biblioteca estática evitará muchos problemas. –

+1

Buen punto. :) La pregunta original sigue en pie, sin embargo, la gente puede usar DLL de alguna manera, ¿no es así? (Además, ¿hay alguna manera fácil de cambiar la compilación de compartida a estática? ¿Será suficiente con Project-> Properties-> General-> Configuration Type-> Static Library?) – neuviemeporte

+0

Los están usando, pero no sin un montón de saltos de aro. En mi humilde opinión, una biblioteca estática siempre debe ser la primera opción. –

Respuesta

2

Mantengo a C++ class library que normalmente se usa como DLL en Windows, por lo que se puede hacer. En cuanto a sus problemas:

  1. Eso no ocurre en mi biblioteca. ¿Quizás necesites usar las opciones de compilación/MD y/MDd? De esta forma, su biblioteca en tiempo de ejecución C++ también proviene de una DLL, que es el tipo de cosa delicada por la que VC++ es famoso.

  2. No utilice las especificaciones throw-specs. They are evil. Si cree que debe hacerlo de todos modos, simplemente ponga algo como esto en un archivo de encabezado que incluya cada módulo antes de que llegue al código que usa throw-specs.

#pragma warning (disable: 4290)

+0

Estoy usando/MD, no ayuda. Whacked todos los ES, sin embargo, después de leer el artículo, gracias. – neuviemeporte

+1

De manera más general, entonces, puede descargar MySQL ++ y echar un vistazo a la configuración de su proyecto para ver por qué el mío funciona y el suyo no. MySQL ++ hace algo similar a su biblioteca: vea lib/exceptions.h, donde obtenemos una clase mysqlpp :: Exception personalizada de std :: exception. –

+1

Eso es porque aparentemente std :: exception * se * exporta en Microsoft-land. Cambié el mío a eso, las advertencias se han ido. – neuviemeporte

1

En primer lugar usted debe preguntarse si realmente necesita una biblioteca dinámica aquí. Las bibliotecas estáticas o incluso mejor que incluyen el código fuente directamente en su proyecto es una buena solución que viene sin esos problemas.

Si realmente necesita la DLL, la forma en que lo haría (dado el tiempo) es ajustar su clase en una interfaz C. A continuación, puede recrear su antigua interfaz de C++ como una biblioteca de solo encabezado C++ que interactúa solo con las llamadas C exportadas desde la DLL. Una característica adicional para este enfoque es que será trivial utilizar su biblioteca desde casi cualquier lenguaje de programación, ya que la importación de funciones C desde DLL es altamente compatible.

Otra forma de hacerlo sería utilizar COM pero, dado que está realizando una migración desde Linux, probablemente no sea una opción.

Cuestiones relacionadas