Dans le Compact Framework 3.5, je tente d'appeler un objet ActiveX qui a une signature de la fonction IDL:.Net Compact Framework - Appel objet ActiveX qui utilise [out] SAFEARRAY (float) *
HRESULT MyFunc([out] SAFEARRAY(float) *var)
Le génération Interop crée le MSIL
[out] class [mscorlib]System.Array& marshal(safearray float32)
Ce qui semble assez raisonnable, mais je continue à obtenir un « NotSupportedException ». Selon un article intitulé "Interop: Problèmes courants et techniques de débogage" (je ne peux pas poster plus d'un hyperlien, c'est le premier résultat google pour cette phrase), dans le premier point sous le titre "Marshaling", le cadre compact ne rassemble pas SAFEARRAYs correctement.
J'ai tenté de contourner ce problème, en manipulant la réponse décrite dans ce post sur le forum MSDN (Dernière entrée décrit sa méthode): http://social.msdn.microsoft.com/forums/en-US/clr/thread/6641abfc-3a9c-4976-a523-43890b2b79a2/
Alors, je l'ai créé la définition suivante:
[StructLayout(LayoutKind.Sequential)]
struct SafeArray
{
public ushort dimensions; // Count of dimensions in the SAFEARRAY
public ushort features; // Flags to describe SAFEARRAY usage
public uint elementSize; // Size of an array element
public uint locks; // Number of times locked without unlocking
public IntPtr dataPtr; // Pointer to the array data
public uint elementCount; // Element count for first (only) dimension
public int lowerBound; // Lower bound for first (only) dimension
}
Et redéfinie le IDL pour la signature de fonction:
HRESULT MyFunc([out] long *var)
Et alors il utilise le code suivant:
IntPtr safeArrayPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(SafeArray)));
SafeArray safeArray;
safeArray.dimensions = 1;
safeArray.features = 0;
safeArray.elementSize = (uint)(Marshal.SizeOf(typeof(float)));
safeArray.locks = 0;
safeArray.elementCount = 6;
safeArray.lowerBound = 0;
safeArray.dataPtr = Marshal.AllocCoTaskMem((int)(safeArray.elementCount * safeArray.elementSize));
Marshal.StructureToPtr(safeArray, safeArrayPtr, false);
int iTmp = safeArrayPtr.ToInt32();
MyFunc(out iTmp)
Alors que le code semble réussir, lorsque je tente de relire les valeurs de données, en utilisant la fonction Marshal.Copy (DataPtr, myFloatArr, faux), je reçois tous les 0 pour les données, ce qui me dit que le pointeur que la DLL ActiveX obtient est probablement totalement faux et il est écrit dans l'oubli.
Avez-vous des suggestions sur ce que j'ai peut-être raté dans ces définitions, ou des suggestions pour d'autres façons d'aborder ce problème?
Merci à l'avance ...