Vous ne pouvez pas renvoyer un tableau d'une fonction comme vous le pensez, mais vous pouvez renvoyer un pointeur sur le tableau. Vous devrez également renvoyer la longueur du tableau afin que vous puissiez correctement marshaler les données au type C# approprié. Cela nécessite une légère modification de la signature de la fonction pour renvoyer à la place les informations via les paramètres transmis à la fonction.
extern "C" EXPORT_API bool GetCharacterPositions(CharacterInformation** data, int *length)
{
CharacterInformation *characterInformationArray = new CharacterInformation[arraysize];
// initialize contents of array.
// ... snip ...
*length = arraysize;
*data = characterInformationArray;
return true;
}
Dans ce cas, vous devrez ajouter un constructeur par défaut à utiliser CharacterInformation
et initialisation à deux phases (à savoir une fonction Init()
). Sachez que vous ne devez pas renvoyer un pointeur ou une référence à une variable locale non statique car le contenu de la variable sera détruit lorsqu'il sort de la portée (c'est-à-dire lorsque la fonction revient).
Pour rassembler les données, vous pouvez essayer quelque chose comme ce qui suit. Ceci n'est pas testé mais devrait vous pousser dans la bonne direction.
[DllImport("Dllname.dll",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool GetCharacterPositions(out IntPtr arrayPtr, out int size);
public static List<CharacterInformation> GetCharacterPositions()
{
var arrayValue = IntPtr.Zero;
var size = 0;
var list = new List<CharacterInformation>();
if (!GetCharacterPositions(out arrayValue, out size))
{
return list;
}
var dataEntrySize = Marshal.SizeOf(typeof(CharacterInformation));
for (var i = 0; i < size; i++)
{
var cur = (CharacterInformation)Marshal.PtrToStructure(arrayValue, typeof(CharacterInformation));
list.Add(cur);
arrayValue = new IntPtr(arrayValue.ToInt32() + dataEntrySize);
}
return list;
}
Vous devrez ajouter un appel supplémentaire afin de supprimer correctement les données en C++, sinon vous finirez avec une fuite de mémoire.
Oke merci, mais comment puis-je convertir ce pointeur un tableau en C#. Je l'ai essayé avec Marshal.PtrToStructure mais cela ne fonctionnera pas pour un tableau. Et je pense que j'ai besoin de connaître la taille du tableau avant d'appeler GetCharacterPositions(), ai-je raison? – ZxCvBnM