2010-06-25 4 views
1

donné cette structure en C#:Copie d'une chaîne de caractères dans une mémoire tampon d'octet de longueur fixe dans une structure

[StructLayout(LayoutKind.Sequential)] 
unsafe public struct AppVPEntry 
{ 
    public int Num; 
    public fixed byte CompName[256]; 
    public int VPBeginAddress; 
} 

Quel est le meilleur moyen de copier une chaîne de caractères (« c: \ chemin \ file.txt ») à la tampon de longueur fixe 'CompName'. C'est dans une structure qui est envoyée à une DLL archaïque que nous n'avons pas d'autre choix que d'utiliser. Idéalement, j'adorerais utiliser une fonction .NET, mais étant donné que c'est corrigé, ce qui signifie «dangereux», je sais que je suis limité ici. Une fonction plus générique aiderait puisque nous avons des chaînes comme ceci partout dans l'espace d'importation de DLL.

+0

À quel encodage les octets sont-ils attendus? –

Répondre

1
// C# to convert a string to a byte array. 
public static byte[] StrToByteArray(string str) 
{ 
    System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); 
    return encoding.GetBytes(str); 
} 

Vous souhaitez probablement vérifier si la taille de la chaîne n'est pas supérieure à la taille du tampon.

+0

J'ai déjà essayé et ça ne marche pas. Cela retournera une structure d'octets gérée, tandis que les définitions 'fixed' et 'unsafe' dans la définition de structure impliquent unmanaged. Merci quand même... – Gio

0

Essayez-le. Utilisez un IntPtr dans votre DllImport partout où vous pourriez passer un VPEntry. Passez le champ "non géré" partout où vous appelez votre méthode DLL.

public sealed class AppVPEntry : IDisposable { 

    [StructLayout(LayoutKind.Sequential, Size = 264)] 
    internal struct _AppVPEntry { 
     [MarshalAs(UnmanagedType.I4)] 
     public Int32 Num; 
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] 
     public Byte[] CompName; 
     [MarshalAs(UnmanagedType.I4)] 
     public Int32 VPBeginAddress; 
    } 

    private readonly IntPtr unmanaged; 
    private readonly _AppVPEntry managed = new _AppVPEntry(); 

    public AppVPEntry(Int32 num, String path, Int32 beginAddress) { 
     this.managed.Num = num; 
     this.managed.CompName = new byte[256]; 
     Buffer.BlockCopy(Encoding.ASCII.GetBytes(path), 0, this.managed.CompName, 0, Math.Min(path.Length, 256)); 
     this.managed.VPBeginAddress = beginAddress; 
     this.unmanaged = Marshal.AllocHGlobal(264); 
     Marshal.StructureToPtr(this.managed, this.unmanaged, false); 
    } 

    public void Dispose() { 
     Marshal.FreeHGlobal(this.unmanaged); 
    } 
} 
Questions connexes