2010-11-05 5 views
4

En C# 4.0, dire que j'aiC#: Convertir Liste des struct simples à octet []

List<HSZPAIR> myList 

avec trois éléments où la struct HSZPAIR est définie par:

[StructLayout(LayoutKind.Sequential)] 
public struct HSZPAIR 
{ 
    public IntPtr hszSvc; 
    public IntPtr hszTopic; 
} 

Comment puis-je créer un tableau d'octets pour toute la myList? En C++, vous pouvez simplement convertir un tableau de structures en un tableau d'octets. Je ne suis pas sûr de savoir comment faire ça en C#.

J'utilise une ancienne fonction API Windows dans la bibliothèque DDEML qui nécessite un tableau d'octets et le nombre d'éléments dans le tableau en tant qu'arguments. Si vous êtes intéressé à plus d'arrière-plan, la fonction API est:

[DllImport("user32.dll", EntryPoint="DdeCreateDataHandle", CharSet=CharSet.Ansi)] 
    public static extern IntPtr DdeCreateDataHandle(int idInst, byte[] pSrc, int cb, int cbOff, IntPtr hszItem, int wFmt, int afCmd); 

Here is it's documentation on MSDN. L'argument pSrc est le tableau d'octets des structures HSZPAIR. La taille du tableau est l'argument cb.

+0

J'ai réussi à convertir une seule structure en un tableau d'octets, étant donné le tutoriel à http://www.developerfusion.com/article/84519/mastering-structs-in-c/. Convertir une liste entière de structures en un tableau d'octets est ce qui me lance pour une boucle. – dmjones

Répondre

1

La conversion d'une structure en un tableau d'octets est plutôt pénible. Vous devez le sérialiser vous-même. Mais cela pourrait ne pas être nécessaire.

Compte tenu de votre liste:

List<HSZPAIR> myList; 

Vous pouvez obtenir un tableau en appelant ToArray:

HSZPAIR[] myArray = myList.ToArray(); 

Maintenant, changer votre prototype géré pour qu'il prenne un HSZPAIR[] plutôt qu'un byte[]:

public static extern IntPtr DdeCreateDataHandle(
    int idInst, HSZPAIR[] pSrc, int cb, int cbOff, IntPtr hszItem, int wFmt, int afCmd); 

Cela devrait fonctionner. Après tout, comme vous l'avez souligné, un tableau de HSZPAIR est vraiment juste un tableau d'octets.

+0

J'aime l'idée, mais la fonction DdeCreateDataHandle est en quelque sorte une fonction polyvalente destinée à convertir des tableaux de données de plusieurs types en un pointeur pour que d'autres fonctions DDE puissent être utilisées. Si je change la déclaration, alors il pourrait casser ces autres usages. La fonction qui crée l'IntPtr créé par DdeCreateDataHandle est supposée savoir quel type de struct les données sont. – dmjones

+0

De plus, je n'ai pas encore assez de réputation pour vous mettre en colère, mais je reviendrai et vous donnerai un sursis une fois que je le ferai. – dmjones

+0

@dmjones: Vous trouverez peut-être ce que vous recherchez dans les exemples de marshaling de tableaux à l'adresse http://msdn.microsoft.com/en-us/library/aa719546(v=VS.71).aspx. Il semble que la page soit cassée, car les exemples C# sont entremêlés avec les exemples VB. Mais là, ils montrent comment organiser des tableaux de plusieurs façons différentes. –

1

Je crois que vous devez définir le type de pSrc dans la déclaration externe comme IntPtr, au lieu de byte [].

+0

Après avoir regardé votre commentaire, j'ai vu via google que d'autres ont défini la définition externe avec un IntPtr ou un octet []. Mais je ne suis pas sûr de savoir comment utiliser un IntPtr au lieu d'un octet [] me rapproche de ce tableau de structures. (De plus, je n'ai pas encore assez de réputation pour vous remonter le moral, mais je reviendrai et vous donnerai un sursis une fois que je le ferai). – dmjones

+0

@dmjones: IntPtr a un peu de "statut privilégié" dans C#; Fondamentalement, cela "fonctionne". –

+0

Je vais essayer, merci. – dmjones

1

Je pense que vous pouvez utiliser Marshal.StructureToPtr. En ce qui concerne la liste elle-même, elle devra être sérialisée séparément.

+0

C'est très similaire à ce que j'ai utilisé du lien Mastering Structs in C# dans mon post original pour marshaling une seule structure, mais je suis sûr que d'autres apprécieront l'info. – dmjones

Questions connexes