.NET CF, Interop & GPS_DEVICE структура - PullRequest
0 голосов
/ 07 октября 2009

Я пытаюсь использовать структуру GPS_DEVICE из .NET CF 3.5, и я продолжаю получать сообщение об ошибке (87), возвращаемое из вызова на GPSGetDeviceState. Насколько я знаю, 87 означает недопустимый параметр, но я не знаю, какой параметр недопустим!

Кто-нибудь может посоветовать, что я сделал не так с моим кодом, так как теперь я провел большую часть двух ночей, не доходя никуда.

Простой тестовый пример ...

NativeMethods.GpsDevice gpsDevice = new NativeMethods.GpsDevice();
int result = NativeMethods.GPSGetDeviceState(ref gpsDevice);

Мое взаимодействие определяется следующим образом ...

private const string GpsApi = @"gpsapi.dll";

private const int GPS_VERSION_1 = 1;
private const int GPS_MAX_SATELLITES = 12;
private const int GPS_MAX_PREFIX_NAME = 16;
private const int GPS_MAX_FRIENDLY_NAME = 64;

[DllImport(GpsApi)]
public static extern int GPSGetDeviceState(ref GpsDevice pGPSDevice);

[StructLayout(LayoutKind.Sequential)]
public class GpsDevice {

public UInt32 dwVersion;

 public UInt32 dwSize;

 public IoctlServiceStatus dwServiceState;

 public IoctlServiceStatus dwDeviceState;

 public FileTime ftLastDataReceived;

 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.GPS_MAX_PREFIX_NAME)]
 public string szGPSDriverPrefix;

 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.GPS_MAX_PREFIX_NAME)]
 public string szGPSMultiplexPrefix;

 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.GPS_MAX_FRIENDLY_NAME)]
 public string szGPSFriendlyName;

 public GpsDevice() {

  this.dwVersion = NativeMethods.GPS_VERSION_1;
  this.dwSize = (UInt32)Marshal.SizeOf(this);

 }

}

[StructLayout(LayoutKind.Sequential)]
public struct FileTime {
 UInt32 dwLowDateTime;
 UInt32 dwHighDateTime;
}

public enum IoctlServiceStatus : uint {

 Off = 0,

 On = 1,

 StartingUp = 2,

 ShuttingDown = 3,

 Unloading = 4,

 Uninitialised = 5,

 Unknown = 0xffffffff

}

Я надеюсь, что я включил всю информацию, которая может потребоваться; если нет, пожалуйста, подскажите мне больше.

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 07 октября 2009

Определите GpsDevice как структуру, а не как класс, затем используйте класс MArshal для преобразования его в неуправляемый код

Смотрите пример здесь, как конвертировать struct в pionter и обратно.

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.structuretoptr.aspx

1 голос
/ 08 октября 2009

Я изменил определение GpsDevice с класса на структуру, и она работает!

[StructLayout(LayoutKind.Sequential)]
public struct GpsDevice {
...

}

Однако пришлось удалить конструктор (именно поэтому я изначально и кодировал его как класс - чтобы я мог автоматически инициализировать члены dwSize и dwVersion).

NativeMethods.GpsDevice gpsDevice = new NativeMethods.GpsDevice {
    dwVersion = NativeMethods.GPS_VERSION_1,
    dwSize = (uint)Marshal.SizeOf(typeof(NativeMethods.GpsDevice))
};

result = NativeMethods.GPSGetDeviceState(ref gpsDevice);

Настоящий позор, что у вас не может быть конструкторов на структурах!

...