2009-10-07 12 views
0

J'essaie d'utiliser la structure GPS_DEVICE à partir de .NET CF 3.5 et je continue d'obtenir une erreur (87) renvoyée par l'appel à GPSGetDeviceState. Pour autant que je sache, 87 signifie paramètre invalide, mais je ne sais pas quel paramètre est invalide!.NET CF, structure Interop & GPS_DEVICE

Quelqu'un peut-il s'il vous plaît aviser de ce que j'ai mal fait avec mon code car j'ai maintenant passé la meilleure partie de deux nuits à ne rien faire.

Le cas de test simple est ...

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

Mon Interop est défini comme suit ...

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 

} 

J'espère avoir inclus toutes les informations qui pourraient être nécessaires; Si ce n'est pas le cas, veuillez m'en aviser.

Merci d'avance.

Répondre

1

j'ai changé la définition du GpsDevice d'une classe à une structure et ça marche!

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

} 

Had pour enlever le constructeur si (ce qui était en fait la raison pour laquelle je codé comme une classe en premier lieu - pour que je puisse automatiquement les membres dwSize initialiser et dwVersion).

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

result = NativeMethods.GPSGetDeviceState(ref gpsDevice); 

Dommage que vous ne puissiez pas avoir de constructeurs sur les structures!

+0

structs ont des constructeurs http://msdn.microsoft.com/en-us/library/aa288208(VS.71).aspx –

+0

Allen - Désolé, peut-être que j'aurais dû être plus précis. Je souhaite que les structures puissent avoir des constructeurs sans paramètres. –

+0

Ajoutez simplement une méthode statique Create qui encapsule l'initialisation de la structure et de la version et renvoie une nouvelle instance de la structure. –

3

Définir GpsDevice comme struct et non pas comme classe, puis utiliser la classe Marshal au maréchal à code non managé

Voir un exemple ici sur la façon de convertir struct à Pionter et le dos.

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

+0

Votre référence à StructureToPtr et PtrToStructure est correcte et fonctionnera aussi bien avec les classes qu'avec les structures (+1). Je m'attendais/espère cependant pouvoir passer la structure en tant que paramètre à l'API GPSGetDeviceState - ceci semble être l'endroit où ma solution échoue. Cela dit, l'indice peut être dans la définition de l'API ... DWORD GPSGetDeviceState ( GPS_DEVICE * pGPSDevice ); Ce qui semble attendre un pointeur! –

+1

Cela ne fonctionnera pas avec la classe, seulement avec struct. C'est la raison pour laquelle elle s'appelle StructToPtr et non ObjectToPtr. –

Questions connexes