agregar ruta de búsqueda DLL personalizada @ inicio de la aplicación
path setdlldirectory (3)
[Editar - Después de volver a leer la pregunta, veo que el problema que está teniendo es que los archivos DLL se cargan antes de los inicios main
]
Supongo que esas bibliotecas están escritas en C ++ y están cargando los archivos DLL desde el constructor de algunos objetos en el alcance global. Esto es problemático Permítanme citar a Yossi Kreinin :
Hazlo primero en main (). Si usa C ++, debe hacerlo primero antes que main (), porque las personas pueden usar FP en constructores de variables globales. Esto puede lograrse averiguando el orden de inicialización de la unidad de traducción específica del compilador, compilando su propia biblioteca de inicio C / C ++, anulando el punto de entrada de una biblioteca de inicio compilada usando cosas como LD_PRELOAD, sobrescribiéndola en un programa enlazado estáticamente allí mismo en la imagen binaria, teniendo una convención de codificación forzando a llamar a FloatingPointSingleton :: instance () antes de usar FP, o disparar a las personas que les gusta hacer cosas antes de main (). Es una compensación.
[Respuesta original a continuación]
Consulte esta página para ver el algoritmo de búsqueda utilizado para cargar archivos DLL. Puede usar SetDllDirectory()
para agregar un directorio a la ruta de búsqueda de DLL.
También debería poder agregar un directorio a la variable de entorno PATH utilizando GetEnvironmentVariable()
y SetEnvironmentVariable()
.
Otra opción es cambiar el directorio de trabajo actual a la carpeta que contiene los archivos DLL con SetCurrentDirectory()
. Solo asegúrese de volver a cambiar el directorio de trabajo después de cargar los archivos DLL si alguna vez carga archivos con nombres de archivo relativos.
Estoy trabajando en mi cerebro tratando de encontrar una solución elegante para un problema de carga de DLL. Tengo una aplicación que enlaza estáticamente a otros archivos lib que cargan archivos DLL. No estoy cargando las DLL directamente. Me gustaría tener algunos archivos DLL en otra carpeta que no sea la carpeta en la que se encuentra el ejecutable. Algo como% working_folder% / dlls - Prefiero no tener docenas (sí ... docenas) de archivos DLL en mi% working_folder% .
Estoy tratando de desarrollar algo que sea parte de la aplicación principal que ajustará la ruta de búsqueda @ inicio. El problema al que me estoy enfrentando es que esta nueva ruta personalizada de DLL no se encuentra en la ruta de búsqueda del sistema. Cuando inicio la aplicación, falla (STATUS_DLL_NOT_FOUND) porque los archivos DLL necesarios no se encuentran en los lugares adecuados. Lo que me gustaría hacer es marcar @ startup si esta nueva carpeta DLL personalizada se encuentra en la ruta de búsqueda de la variable de entorno de proceso y, si no, agréguela. El problema es que la aplicación intenta cargar todas estas DLL antes de que la aplicación ejecute una línea de código.
¿Cómo puedo solucionar esto? Consideré escribir una aplicación de ayuda que comience primero, ajuste las variables de entorno de forma adecuada y lance la aplicación principal a través de CreateProcess. Esto funcionará, estoy seguro, pero dificulta las cosas a los desarrolladores. Cuando depuran la aplicación principal, no van a lanzar primero una aplicación de ayuda, ni siquiera podrían hacer eso.
Probé la función de ruta de la aplicación de registro sin éxito. Mismo problema de huevo y pollo que antes.
¿Qué puedo hacer aquí?
Mi recomendación es utilizar la vinculación de la carga de retraso para los archivos DLL y llamar a SetDllDirectory () lo suficientemente temprano para que pueda encontrarlos cuando se invoquen los métodos / funciones.
Descubrí que la respuesta de Matthew funcionó para mí.
En Visual Studio 2012, vaya a las propiedades de su proyecto y en Propiedades de configuración-> Enlazador-> Entrada-> Delay Loaded Dlls agregue cada archivo dll que no quiera cargar hasta que lo necesite.
Aunque ya no es necesario ejecutar antes de main, este es mi código para establecer la nueva ruta de búsqueda
class RunBeforeMain
{
public:
RunBeforeMain()
{
const TCHAR* dllPathEnvName= name of env variable to directory containing dlls
const TCHAR* pathEnvName= TEXT("Path");
TCHAR newSearchPath[4096];
::GetEnvironmentVariable(dllPathEnvName, newSearchPath, MAX_PATH);
//append bin
_tcscat_s(newSearchPath, MAX_PATH, TEXT("bin;"));
size_t length = _tcslen(newSearchPath);
//append existing Path
::GetEnvironmentVariable(pathEnvName, newSearchPath + length, 4096-length);
::SetEnvironmentVariable(pathEnvName, newSearchPath);
}
};
static RunBeforeMain runBeforeMain; //constructor code will run before main.