Я пытаюсь написать оболочку С# P/Invoke для C API (собственная Win dll), и в целом это работает нормально. Единственным исключением является конкретный метод, который принимает структуру в качестве параметра в коде C. Функция вызывается без каких-либо исключений, но возвращает false, указывая на то, что при выполнении произошел сбой.
В заголовочном файле API задействованный метод и структуры определены следующим образом:
#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*/);
Я попытался создать оболочку C# P/Invoke, используя следующий код:
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);
Затем я пытаюсь вызвать метод EncodeMagstripe, используя следующий код C#:
CardApi.MSTrackData trackNull = null;
CardApi.MSTrackData track2 = new CardApi.TrackData();
byte[] trackBytes = Encoding.ASCII.GetBytes(";0123456789?");
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());
}
Это вызывает исключение ApplicationException и код ошибки 801, что, согласно документации, означает «Данные содержат слишком много символов для выбранного формата дорожки 2». Однако выбранный формат дорожки должен содержать до 39 символов (я пробовал и более короткие строки).
Я подозреваю, что проблема возникает из-за того, что я сделал что-то неправильно в определении MSTrackData, но я не вижу, что это может быть. У кого-нибудь есть предложения?