c# c++ dll pinvoke

c# - No se puede cargar la DLL(No se pudo encontrar el módulo HRESULT: 0x8007007E)



c++ pinvoke (14)

Tengo una biblioteca dll con un código API de C ++ no administrado que necesito usar en mi aplicación .NET 4.0. Pero cada método que intento cargar mi dll me da un error:

No se pudo cargar la DLL ''MyOwn.dll'': no ​​se pudo encontrar el módulo especificado. (Excepción de HRESULT: 0x8007007E)

He leído y probado varias soluciones que he encontrado en Internet. Nada funciona..

He intentado usar los siguientes métodos:

[DllImport("MyOwn.dll", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs((UnmanagedType.I4))] public static extern Int32 MyProIni(string DBname, string DBuser_pass, string WorkDirectory, ref StringBuilder ErrorMessage);

Cuando traté de seguir este artículo y cuando ejecuto este ejemplo (desde el código descargado) se ejecuta sin problemas (el dll utilizado está en la carpeta bin / debug)

He copiado mi dll (junto con todos los archivos de los que depende en mi carpeta bin).

También probé este enfoque, pero obtuve el mismo error:

[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")] [return: MarshalAs(UnmanagedType.I4)] public static extern int MyproIni(string DBname, string DBuser_pass, string WorkDirectory, ref StringBuilder ErrorMessage);

¿Alguna sugerencia?


Active el registro de fusión, consulte esta pregunta para obtener muchos consejos sobre cómo hacerlo. La depuración de problemas de carga de aplicaciones de modo mixto puede ser un verdadero dolor real. El registro de fusión puede ser de gran ayuda.


Asegúrese de configurar el objetivo de la plataforma de compilación en x86 o x64 para que sea compatible con su DLL, que podría compilarse para una plataforma de 32 bits.


Asegúrese de que todas las dependencias de su propio dll estén presentes cerca de la dll o en System32 .


Creo que su biblioteca no administrada necesita un manifiesto.
Here es cómo agregarlo a tu binario. y here está el porqué

En resumen, varias versiones de la biblioteca redistribuible se pueden instalar en su caja, pero solo una de ellas debería satisfacer su aplicación, y es posible que no sea la predeterminada, por lo que necesita decirle al sistema la versión que necesita su biblioteca, por eso el manifiesto.


Esto es un ''kludge'', pero al menos podrías usarlo para probar la cordura: prueba codificando la ruta de la DLL en tu código

[DllImport(@"C://mycompany//MyDLL.dll")]

Una vez dicho esto; en mi caso, ejecutar dumpbin /DEPENDENTS según lo sugerido por @ anthony-hayward, y copiar versiones de 32 bits de las DLL listadas allí en mi directorio de trabajo resolvió este problema para mí.

El mensaje es un poco engañoso, porque no es "mi" dll el que no se puede cargar, son las dependencias


Hay una cosa muy divertida (y tiene una relevancia técnica) que podría desperdiciar tus horas, así que pensé en compartirla aquí:

ClassLibrary1 un proyecto de aplicación de consola ConsoleApplication1 y un proyecto de biblioteca de clases ClassLibrary1 .

Todo el código que estaba haciendo el p / ClassLibrary1.dll estaba presente en ClassLibrary1.dll . Así que antes de depurar la aplicación de Visual Studio simplemente copié el ensamblado no administrado de C ++ ( myUnmanagedFunctions.dll ) en el directorio /bin/debug/ del proyecto ClassLibrary1 para que el CLR pueda cargarlo en tiempo de ejecución.

Seguí recibiendo el

No se puede cargar la DLL

error por horas Más tarde me di cuenta de que todos los ensamblajes no administrados que se van a cargar deben copiarse en el directorio /bin/debug del proyecto de inicio ConsoleApplication1 que generalmente es un formulario ganador, consola o aplicación web.

Por lo tanto, tenga cuidado, el Current Directory en la respuesta aceptada en realidad significa el Current Directory del ejecutable principal desde donde se inicia el proceso de solicitud. Parece una cosa obvia, pero a veces no es así.

Lección aprendida : siempre coloque las dlls no administradas en el mismo directorio que el ejecutable de inicio para garantizar que se pueda encontrar.


Intenta ingresar el camino completo de la dll. Si no funciona, intente copiar el dll en la carpeta system32.


Me he encontrado con el mismo problema. En mi caso, tenía dos PC de 32 bits. Uno con .NET4.5 instalado y otro con PC reciente.

mi cpp dll de 32 bits (versión de modo de lanzamiento) funcionaba bien con PC instalada .NET pero no con PC reciente donde obtuve el siguiente error

Imposible cargar DLL ''PrinterSettings.dll'': no ​​se pudo encontrar el módulo especificado. (Excepción de HRESULT: 0x8007007E)

finalmente,

Acabo de construir mi proyecto en la configuración del modo de depuración y esta vez mi dll cpp estaba funcionando bien.


Por lo que recuerdo en Windows, el orden de búsqueda de un dll es:

  1. Directorio actual
  2. Carpeta del sistema, C:/windows/system32 or c:/windows/SysWOW64 (para el proceso de 32 bits en el cuadro de 64 bits).
  3. Lectura de la variable de entorno Path

Además, verificaría las dependencias de la DLL, la migración de dependencias proporcionada con Visual Studio puede ayudarte aquí, también se puede descargar de forma gratuita: http://www.dependencywalker.com


Puede usar la herramienta dumpbin para averiguar las dependencias DLL requeridas:

dumpbin /DEPENDENTS my.dll

Esto le dirá qué DLL necesita cargar su DLL. En particular, tenga cuidado con MSVCR * .dll. He visto que se produce el código de error cuando no está instalado el redistribuible de Visual C ++ correcto.

Puede obtener los "Paquetes redistribuibles de Visual C ++ para Visual Studio 2013" en el sitio web de Microsoft. Se instala c: / windows / system32 / MSVCR120.dll

En el nombre del archivo, 120 = 12.0 = Visual Studio 2013.

Tenga cuidado de tener la versión correcta de Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) arquitectura correcta (x64 o x86) para la plataforma de destino de su DLL, y también debe tener cuidado con construcciones de depuración. La compilación de depuración de una DLL depende de MSVCR120d.dll que es una versión de depuración de la biblioteca, que se instala con Visual Studio pero no con el paquete redistribuible.


Si el DLL y los proyectos .NET están en la misma solución y desea compilar y ejecutar ambos en todo momento, puede hacer clic con el botón derecho en las propiedades del proyecto .NET, generar eventos y luego agregar algo como lo siguiente al evento Post-build. línea de comando:

copy $(SolutionDir)Debug/MyOwn.dll .

Básicamente es una línea de DOS, y puede modificarla según el lugar en el que se está creando su DLL.


Tuve el mismo problema cuando implementé mi aplicación para probar la PC. El problema era que el PC de desarrollo tenía msvcp110d.dll y msvcr110d.dll pero no la PC de prueba.

Agregué el módulo de fusión "Visual Studio C ++ 11.0 DebugCRT (x86)" en InstalledSheild y funcionó. Espero que esto sea útil para otra persona.


Configuración : Windows 7 de 32 bits

Contexto : instalé un controlador PCI-GPIB que no pude comunicar debido al problema mencionado anteriormente.

Respuesta corta : reinstalar el controlador.

Respuesta larga : también utilicé Dependency Walker , que identificó varios módulos de dependencia faltantes. Inmediatamente, pensé que debía tratarse de una instalación de controlador fallida. No quería verificar y restaurar cada archivo perdido.

El hecho de que no pude encontrar el desinstalador en Programas y características del Panel de control es otro indicador de la mala instalación. Tuve que eliminar manualmente un par de * .dll en / system32 y claves de registro para permitir la reinstalación del controlador.

Problema solucionado

La parte inesperada fue que no todos los módulos de dependencia se resolvieron. Sin embargo, ahora se puede hacer referencia al * .dll de interés.


La DLL debe estar en la carpeta bin.

En Visual Studio, agrego el dll a mi proyecto (NO en Referencias, sino "Agregar archivo existente"). A continuación, establezca la propiedad "Copiar en directorio de salida" para el archivo dll en "Copiar si es más nuevo".