/ / Módulos dinámicos con DLL en Windows: c, windows, dll, módulo, carga diferida

Módulos dinámicos con DLL en Windows - c, windows, dll, module, lazy-loading

Estoy escribiendo una aplicación en C que puede serextendido en tiempo de ejecución por medio de módulos / objetos compartidos / DLL. Esos módulos pueden usar la API del programa existente, pero también pueden proporcionar nuevas funciones para su uso en módulos cargados posteriormente, por lo que existe la posibilidad de que los módulos tengan dependencias entre sí.

Mi enfoque actual en Linux es tener cadaEl módulo define una función depend () que devuelve una lista de otros nombres de módulos de los que depende. De esa manera, puedo compilar y vincular cada módulo por sí mismo, cargar un módulo con dlopen () y RTLD_LAZY, resuelva sus dependencias primero y luego cárguelo completamente con RTLD_GLOBAL. Esto funciona bien y hace exactamente lo que quiero. También me permite reemplazar un módulo con una versión diferente sin recompilar todos los demás módulos dependiendo de él.

El problema real surge al portar esto aWindows Primero, no he encontrado ninguna manera de vincular una DLL sin proporcionarle las tablas de símbolos de exportación de todas sus dependencias. ¿Hay alguna que haya pasado por alto?

En segundo lugar, LoadLibraryEx de la API de Windowsno parece ser capaz de realizar ninguna carga diferida porque en lugar de permitirme manejar dependencias, continúa y carga todas las DLL referenciadas antes incluso de que regrese. Ya que me gustaría realizar la verificación de versiones también antes de cargar realmente los módulos en el futuro, esto no es para nada lo que quiero. ¿Hay alguna forma de eludir este comportamiento?

La tercera cosa extraña es que no puedo reemplazar unDLL sin recompilar todos los demás módulos dependiendo de él. En realidad, funciona a veces, pero generalmente comienzan a suceder cosas salvajes o el programa falla.

¿Es posible incluso escribir una aplicación modular como esa en Windows? Cualquier sugerencia o diferentes enfoques son muy apreciados!

Actualizar: Solo para proporcionar algunas aclaraciones sobre cómo milos módulos usan las funciones de los demás en Linux (que también me gustaría tener en Windows): cada módulo solo devuelve el nombre de otro módulo desde el que desea llamar a las funciones en la función depend () descrita e incluye su encabezado, luego llama Las funciones utilizadas directamente en el código sin ningún ajuste. Esto funciona porque Linux no requiere que resuelva todos los símbolos en el momento del enlace para los objetos compartidos.

Respuestas

4 para la respuesta № 1

Puede exportar todas las funciones manualmente (usando __declspec(dllexport)) y cárguelos usando GetProcAddress. En este caso necesita saber la firma decada función, y usted está limitado a las funciones de C solamente, pero esto funcionará. Si compila ambos módulos, sus funciones de C también pueden devolver clases de C ++, más sobre esto más adelante. GetProcAddress & LoadLibrary hace que los módulos sean totalmente independientes. Básicamente, haces el enlace manualmente, pero según tengo entendido, esto es lo que haces en Linux, ¿verdad?

LoadLibary solo carga las bibliotecas de las que depende una bibliotecaencendido, así que asegúrese de que no se carguen entre sí. O son realmente independientes o no lo son, si se hace correctamente, cambiar una biblioteca no forzará una recompilación de la otra (ya que no las vincula juntos).

Una buena idea es usar algo como COM, así que hazcada una de sus bibliotecas devuelve una interfaz, en lugar de funciones individuales. De esa manera, simplemente puede cargar una DLL completa y también vincularlas fácilmente (pasando una DLL -> pasando un objeto). Busque XPCOM y COM, en realidad es muy fácil de hacer.