Al di là del titolo stupido, i problemi di "convivenza" tra PocketPC e codice nativo C++ che citavo in precedenza sono stati risolti grazie alla segnalazione di Stefano Ottaviani : su MSDN ci sono una serie di articoli che spiegano + o - tutto quello che c'è da sapere... compreso il problema della ridenominazione dei metodi, che in realtà si chiama Name Mangling: basta aggiungere alla firma dei metodi extern  "C" per evitare la modifica del nome dei metodi!

Per quanto riguarda il problema dell'eccezione NotSupportedException generata se si usano come tipo di ritorno double o string (vedete il post precedente per chiarire il tipo di problema a cui mi riferisco), l'eccezione viene ovviamente generata dal codice .NET, come riportato qui:

" This occurs if the arguments passed to the method contain invalid data, or if the function itself is declared with improper arguments. In this case, a NotSupportedException will be thrown. If this occurs, you should re-examine your declaration to determine if it matches the actual DLL definition. "

Quindi, semplicemente, una firma come questa

__declspec(dllexportdouble __stdcall DBFReadDoubleAttributeDBFHandle hDBFint iShapeint iField,);

nel Framework 1.1 richiede questa dichirarazione DllImport,

[DllImport("shapelib.dll"CharSet=CharSet.Unicode)]
public static extern double DBFReadDoubleAttribute (IntPtr hDBFint iShapeint iField);

dichiarazione che però non è valida per il Compact Framework! Per capirne il motivo basta continuare nell'articolo indicato in precedenza, e controllare la lista dei Blittable Types, ovvero:

" ... types will have a common representation in both the .NET Compact Framework and unmanaged code.

CF type VB keyword C# keyword
System.Byte

Byte

byte
System.SByte n/a sbyte
System.Int16 Short short
System.UInt16 n/a ushort
System.Int32 Integer int
System.Int64 Long (only ByRef) long (only ref)
System.UInt64 n/a ulong

System.IntPtr
System.Char
System.String
System.Boolean  

n/a
Char
String
Boolean

* using unsafe
char
string
bool

In other words, the marshaler doesn't need to perform any special handling of parameters defined with these types in order to convert them between managed and unmanaged code. In fact, by extension, the marshaler needn't convert one-dimensional arrays of these types, or even structures and classes that contain only these types. "

Come si vede non ci sono i tipi double, e + in generale non interi; infatti...

" These types cannot be marshaled by value by the .NET Compact Framework. However, they can be marshaled by reference, and passed as pointers to an unmanaged function that acts as a wrapper or shim. "

Per quanto riguarda le stringhe invece...

As just mentioned, strings in the .NET Compact Framework are blittable types, and are represented to unmanaged functions as null-terminated arrays of Unicode characters. At invocation time, since System.String is a reference type (it is allocated on the managed heap, and its address is stored in the reference variable), and even though it is being passed by value, the marshaler passes a pointer to the string to the unmanaged function... ".

Presumo quindi che sia per questo motivo che nei fatti una funzione C++ di questo tipo:

__declspec(dllexportconst wchar_t__stdcall DBFReadStringAttributeDBFHandle hDBFint iShapeint iField,);

non funzioni con questa DllImport

[DllImport("shapelib.dll", CharSet=CharSet.Unicode)]
public static extern string DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);

comportandosi esattamente come la precedente funzione che ritorna un double.

In conclusione, perchè il titolo "la rivincita di .NET" ?

Semplice, xchè, seguendo il suggerimenti di Roberto Messora, alla fine ho optato per gestire in .NET la lettura/scrittura dei DBF, a partire dalle funzioni IO presenti in GeoTools.NET!

powered by IMHO 1.3