Aquí está el código C++ dll:
#include<stdlib.h> #include "pch.h" extern "C" _declspec(dllexport) int Add(int a, int b) { return a + b; }Código C#, que ejecuto en Visual Studio:
[DllImport(@"C:\Dll1.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern int Add(int port, int speed); public static void Main() { int res = Add(8, 11); Console.WriteLine(res); } Sin problemas, salida: 19
Código de PowerShell:
Add-Type -Name MyFunctions -Namespace Cpp @' [DllImport(@"C:\Dll1.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern int Add(int port, int speed); '@ [Cpp.MyFunctions]::Add(8, 11) Salida: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
Pero las funciones de user32.dll/kernel32.dll se importan sin ningún problema.
¿Como arreglarlo?
Asegúrese de que está utilizando dll de 32 bits para el proceso de PowerShell de 32 bits y dll de 64 bits para el proceso de PowerShell de 64 bits. El error parece como si estuviera tratando de cargar dll de 32 bits en un proceso de 64 bits. Tenga en cuenta que las aplicaciones .net compiladas como "Cualquier CPU" se ejecutarán en modo de 32 bits de manera predeterminada, incluso en sistemas operativos de 64 bits.
Actualizar
Si tiene una fuente para su dll, debe volver a compilarla para un entorno de 64 bits y luego importar esta compilación de 64 bits.
Si necesita ejecutar el script PS en entornos PowerShell de 32 y 64 bits, debe implementar dos versiones de dll y seleccionar la correcta en tiempo de ejecución. No sé cómo se puede hacer esto para PS, pero para la solución C# puede usar una solución basada en #ifdef como se describe aquí: Uso de una dll de 32 o 64 bits en C# DllImport
Si no tiene fuentes para su dll, entonces todo se vuelve complicado y no conozco ninguna solución directa aquí. Puede intentar envolver su archivo DLL en el servidor COM en proceso (o incluso fuera de proceso) de 32 bits (con la ayuda de C# o C++) y luego usar este servidor con New-Object . Como sé, Windows tiene correcciones especiales que permiten utilizar objetos COM de 32 bits desde un proceso de 64 bits y viceversa, pero no estoy seguro de si esto funcionará para PS o no.
Para las DLL integradas, Windows tiene una redirección automática de rutas de archivos de System32 a SysWOW64. Por lo tanto, cuando solicite la importación de user32, obtendrá diferentes bibliotecas de user32 según el bitness de su proceso. Puede leer más sobre esto aquí: PowerShell de 64 bits llama a la DLL de 32 bits