Question

J'ai vraiment du mal à obtenir ce marshalling vers le bas.

J'ai le code umanaged qui ressemble à ceci:

WORD HLP_GetDeviceNames (LPSTR *DevNames, WORD Max_Len, WORD Max_Num)

Juste Pour votre information, je n'a pas écrit ce code non managé mais doit l'utiliser.

Renvoie:. WORD indiquant une erreur

DEVNAMES: pointeur sur un tableau de tableaux char. Fondamentalement, un tableau de chaînes qui sera modifié et retourné à moi!

Max_Len: Longueur de chaque chaîne (on me dit cela doit être 256)

MAX_NUM: Longueur du tableau. J'utilise un autre appel Invoke qui travaille qui me dit nombre de périphériques, donc je sais exactement combien de chaînes à envoyer.

Je l'ai utilisé la signatureToolkit P / Invoke à la figure beaucoup de ceci, mais lire aussi un tas d'obtenir encore plus loin. Là où je suis maintenant ici:

[DllImport("UsbMeasLib.dll")]
public static extern ushort HLP_GetDeviceNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] ref StringBuilder[] DevNames, ushort Max_Len, ushort Max_Num);

J'appelle mon code comme ceci:

StringBuilder[] DevNames = new StringBuilder[deviceCount];
     for(int i = 0; i< deviceCount; i++)
     {
           DevNames[i] = new StringBuilder().Append(' ', 256);
     }

     HachUsbMeasLib.HLP_GetDeviceNames(ref DevNames, 256, Convert.ToUInt16(DevNames.Count())); 

J'utilise tableau constructeur de chaîne parce que je besoin du code non managé pour modifier le constructeur de chaîne afin qu'elle puisse retourner la nouvelle chaîne depuis la chaîne est unmutable.

Quand je lance le code, Mon tableau est non modifiée!

Je ne suis pas vraiment sûr de ce qui se passe mais je pense qu'il a quelque chose à voir avec CLR dire code non managé de ne pas modifier mon tableau en place, mais crée plutôt une nouvelle référence (pointeur). Même si tel est le cas, je ne sais pas comment le résoudre.

Merci pour toute personne insight peut offrir!

Était-ce utile?

La solution 2

je me suis dit celui-ci dehors. Merci à tous ceux qui ont répondu.

J'ai découvert comment cela fonctionne. Je fournir simplement l'espace mémoire, mais je dois laisser savoir que je marshaling attends et avec cet objet il permet au code non managé de modifier l'espace alloué.

Je l'ai fait comme ceci:

[DllImport("UsbMeasLib.dll")]
private static extern ushort HLP_GetDeviceNames([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string[] DevNames, ushort Max_Len, ushort Max_Num);

J'utilise la chaîne au lieu de chaîne constructeur, car le code non managé remplacera simplement la chaîne qui est ok. Je reçois le pointeur tableau arrière, pas les chaînes modifiées. le code géré est juste en train de changer un tableau de pointeurs pour pointer vers de nouveaux objets à cordes (je pense).

int numDev = HLP_GetNumDevices();


string[] names = new string[numDev];

for (int i = 0; i < names.Length; i++)
{
    names[i] = new StringBuilder().Append(' ', 256).ToString();
}

ushort errorCode = HLP_GetDeviceNames(names, 256, Convert.ToUInt16(numDev));

J'allouer de la mémoire pour le code unamanged puis laisser le code non managé Chane les chaînes là.

Cela fonctionne, mais je ne sais pas si j'ai des éventuelles fuites de mémoire ou d'autres problèmes potentiels.

Autres conseils

Essayez de travaux bas niveau. Declare DEVNAMES paramètre IntPtr []. Préparer par la manière suivante:

IntPtr[] devNames = new IntPtr[deviceCount];

for(int i = 0; i < deviceCount; i++) 
{ 
    devNames[i] = Marshal.AllocHGlobal[256];
}

Passez à ce tableau HLP_GetDeviceNames. Pour traiter les données de sortie, appliquer Marshal.PtrToStringAnsi à tous les membres de DEVNAMES. Ne pas oublier de libérer DEVNAMES [i] avec Marshal.FreeHGlobal à la fin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top