Estoy tratando de escribir un contenedor C# P/Invoke para una API C (una DLL nativa Win), y generalmente esto está funcionando bien. La única excepción es un método específico que toma una estructura como parámetro en el código C. La función se invoca sin excepciones, pero devuelve falso indicando que algo falló en la ejecución.C# P/Problema de estructura de invocación
En la cabecera API presentar el método y estructuras implicados se definen como sigue:
#define MAX_ICE_MS_TRACK_LENGTH 256
typedef struct tagTRACKDATA
{
UINT nLength;
BYTE TrackData[MAX_ICE_MS_TRACK_LENGTH];
} TRACKDATA, FAR* LPTRACKDATA;
typedef const LPTRACKDATA LPCTRACKDATA;
BOOL ICEAPI EncodeMagstripe(HDC /*hDC*/,
LPCTRACKDATA /*pTrack1*/,
LPCTRACKDATA /*pTrack2*/,
LPCTRACKDATA /*pTrack3*/,
LPCTRACKDATA /*reserved*/);
he hecho un intento de crear un C# P/Invoke envoltura mediante el siguiente código:
public const int MAX_ICE_MS_TRACK_LENGTH = 256;
[StructLayout(LayoutKind.Sequential)]
public class MSTrackData {
public UInt32 nLength;
public readonly Byte[] TrackData = new byte[MAX_ICE_MS_TRACK_LENGTH];
}
[DllImport("ICE_API.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EncodeMagstripe(IntPtr hDC,
[In]ref MSTrackData pTrack1,
[In]ref MSTrackData pTrack2,
[In]ref MSTrackData pTrack3,
[In]ref MSTrackData reserved);
entonces trato de invocar el método EncodeMagstripe usando el siguiente código C#:
CardApi.MSTrackData trackNull = null;
CardApi.MSTrackData track2 = new CardApi.TrackData();
byte[] trackBytes = Encoding.ASCII.GetBytes(";?");
track2.nLength = (uint)trackBytes.Length;
Buffer.BlockCopy(trackBytes, 0, track2.TrackData, 0, trackBytes.Length);
if (!CardApi.EncodeMagstripe(hDC, ref trackNull, ref track2, ref trackNull, ref trackNull)) {
throw new ApplicationException("EncodeMagstripe failed", Marshal.GetLastWin32Error());
}
Th provoca una excepción ApplicationException, y el código de error es 801, que según la documentación significa "Los datos incluyen demasiados caracteres para el formato Track 2 seleccionado". Sin embargo, el formato de pista seleccionado debe permitir hasta 39 caracteres (también he probado cadenas más cortas).
Sospecho que el problema se debe a algo que hice mal en la definición de MSTrackData, pero no puedo ver lo que puede ser. ¿Alguien tiene alguna sugerencia?
ICEAPI se refiere a WINAPI, por lo que también configuro "CallingConvention = CallingConvention.Winapi" en el atributo DllImport. Después de implementar su sugerencia, la llamada funcionó perfectamente :-) Muchas gracias :-) –