Tengo una biblioteca dll con código API C ++ no administrado que necesito usar en mi aplicación .NET 4.0. Pero cada método que intento cargar mi dll me sale un error:
No se puede 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 utilizar 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 intenté seguir este artículo y cuando ejecuto este ejemplo (del 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?
Puede utilizar la herramienta dumpbin para averiguar las dependencias DLL necesarias:
Esto le dirá qué DLL necesita cargar su DLL. En particular, busque MSVCR * .dll. He visto que su código de error se produce cuando el Visual C ++ Redistributable correcto no está instalado.
Puede obtener los "Paquetes redistribuibles de Visual C ++ para Visual Studio 2013" en el sitio web de Microsoft. 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 adecuada (x64 o x86) para la plataforma de destino de su DLL, y también debe tener cuidado con depurar compilaciones. 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.
fuente
debug
binario, la versión de los redistribuibles en tiempo de ejecución de C ++ debe ser exactamente la misma que donde la construyó.Esto es un 'kludge' pero al menos podría usarlo para probar la cordura: intente codificar la ruta a la DLL en su código
Una vez dicho esto; en mi caso, ejecutar
dumpbin /DEPENDENTS
como lo sugiere @ anthony-hayward, y copiar más de las versiones de 32 bits de las DLL enumeradas allí en mi directorio de trabajo resolvió este problema para mí.El mensaje es un poco engañoso, porque no es "mi" dll que no se puede cargar, son las dependencias
fuente
La DLL debe estar en la carpeta bin.
En Visual Studio, agrego el dll a mi proyecto (NO en Referencias, sino en "Agregar archivo existente"). Luego, establezca la propiedad "Copiar en el directorio de salida" de la dll en "Copiar si es más reciente".
fuente
Intente ingresar la ruta completa de la dll. Si no funciona, intente copiar el dll en la carpeta system32.
fuente
Asegúrese de que todas las dependencias de su propia dll estén presentes cerca de la dll o en
System32
.fuente
Hay una cosa muy divertida (y tiene una relevancia técnica) que podría desperdiciar sus horas, así que pensó en compartirla aquí:
Creé un proyecto de aplicación de consola
ConsoleApplication1
y un proyecto de biblioteca de clases.ClassLibrary1
.Todo el código que estaba haciendo p / invoke estaba presente en
ClassLibrary1.dll
. Entonces, antes de depurar la aplicación desde Visual Studio, simplemente copié el ensamblado no administrado de C ++ (myUnmanagedFunctions.dll
) en el\bin\debug\
directorio delClassLibrary1
proyecto para que CLR pueda cargarlo en tiempo de ejecución.Seguí recibiendo el
error durante horas. Más tarde me di cuenta de que todos los ensamblados no administrados que se van a cargar deben copiarse en el
\bin\debug
directorio del proyecto de inicio,ConsoleApplication1
que generalmente es un formulario win, una consola o una aplicación web.Por lo tanto, tenga cuidado de que
Current Directory
en la respuesta aceptada en realidad significa elCurrent Directory
ejecutable principal desde donde se inicia el proceso de aplicación. Parece algo obvio, pero a veces puede que no lo sea.Lección aprendida : coloque siempre las DLL no administradas en el mismo directorio que el ejecutable de inicio para asegurarse de que se puedan encontrar.
fuente
bin\Debug
y losobj\Debug
directorios y me siguen dando el "No se puede DLL de carga"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 de cabeza. El registro de fusión puede ser de gran ayuda.
fuente
Asegúrese de configurar Build Platform Target en x86 o x64 para que sea compatible con su DLL, que podría estar compilado para una plataforma de 32 bits.
fuente
Si los proyectos DLL y .NET están en la misma solución y desea compilar y ejecutar ambos cada vez, puede hacer clic con el botón derecho en las propiedades del proyecto .NET, Eventos de compilación y luego agregar algo como lo siguiente al evento posterior a la compilación línea de comando:
Básicamente es una línea de DOS, y puede ajustar según dónde se construya su DLL.
fuente
Tuve el mismo problema cuando implementé mi aplicación para probar la PC. El problema era que la PC de desarrollo tenía
msvcp110d.dll
ymsvcr110d.dll
pero no el PC de prueba.Agregué el módulo de combinación "Visual Studio C ++ 11.0 DebugCRT (x86)" en InstalledSheild y funcionó. Espero que esto sea útil para otra persona.
fuente
En mi caso, una dll no administrada dependía de otra que faltaba. En ese caso, el error apuntará a la dll existente en lugar de la que falta, lo que puede ser realmente confuso.
Eso es exactamente lo que sucedió en mi caso. Espero que esto ayude a alguien más.
fuente
Creo que su biblioteca no administrada necesita un manifiesto.
Aquí se explica cómo agregarlo a su binario. y aqui por qué.
En resumen, se pueden instalar varias versiones de la biblioteca redistribuible en su caja, pero solo una de ellas debería satisfacer su aplicación, y puede que no sea la predeterminada, por lo que debe indicarle al sistema la versión que necesita su biblioteca, por eso el manifiesto.
fuente
Configuración : Windows 7 de 32 bits
Contexto : instalé un controlador PCI-GPIB con el que no pude comunicarme debido al problema mencionado anteriormente.
Respuesta corta : reinstale el controlador.
Respuesta larga : también utilicé Dependency Walker , que identificó varios módulos de dependencia faltantes. Inmediatamente, pensé que debía haber sido una instalación de controlador fallida. No quería comprobar y restaurar cada archivo que faltaba.
El hecho de que no pude encontrar el desinstalador en Programas y características del Panel de control es otro indicador de una 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 se resolvieron todos los módulos de dependencia. Sin embargo, ahora se puede hacer referencia al * .dll de interés.
fuente
Me he encontrado con el mismo problema, en mi caso tenía dos PC de 32 bits. Uno con .NET4.5 instalado y el otro era una PC nueva.
mi cpp dll de 32 bits (compilación en modo de lanzamiento) funcionaba bien con una PC instalada en .NET pero no con una PC nueva donde recibí el siguiente error
finalmente,
fuente
También enfrentó el mismo problema al usar un archivo dll c / c ++ no administrado en el entorno c #.
1.Comprueba la compatibilidad de dll con CPU de 32 bits o 64 bits.
2. Verifique las rutas correctas de la carpeta DLL .bin, system32 / sysWOW64 o la ruta dada.
3.Compruebe si faltan archivos PDB (base de datos de programas) .Este video le brinda una mejor comprensión de los archivos pdb.
Al ejecutar código binario C / C ++ de 32 bits en un sistema de 64 bits, esto podría surgir debido a la incompatibilidad de la plataforma. Puede cambiarlo desde Compilación> Administrador de configuración.
fuente
Enfrenté el mismo problema al importar C ++ Dll en .Net Framework +4, desmarqué Proyecto-> Propiedades-> Compilación-> Preferir 32 bits y se resolvió por mí.
fuente