2013-01-31 30 views
9

Eski bir Visual BASIC programını C# 'a dönüştürüyorum. Bazı endüstriyel makinelere ethernet üzerinden mesajlar gönderir. Bunu yapmak için sabit boyutlu kullanıcı tanımlı parçalardan bir bayt akışı oluşturur.C# cinsinden sabit boyutlu bayt dizisi kullanıcı türünü nasıl yapabilirim?

bu parçalar çoğu küçük ve C# biz gitmek böylece zaman ... Örneğin

[StructLayout(LayoutKind.Sequential, Pack = 1)] 

için, birkaç bayt veya ints yapılar oluşturmak ve StructLayout en kullanarak boyutunu ve düzenini kontrol etmek kolaydır bytewise bir kopya yapmak için yönetilmeyen alan biz bayt sipariş veya doldurma sorunları yok.

Ama VB6 yapılarının bazı

Private Type SEND_MSG_BUFFER_320_BYTES 
    bytes(0 To 319) As Byte '320 bytes 
End Type 

, örneğin, büyük dizilerdir ve C# bunu nasıl birlikte mücadele ediyorum. Ben zamanında ve System.Runtime.InteropServices.Marshal bu boyutunu keşfetmek gerekiyor bit odaklı kopyasını yapmak ama

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public class SOME_BYTES 
    { 
     public byte[] b = new byte[320]; 
    } 

, örneğin bir sınıfta bir sabit boyutlu dizi yapabilirsiniz. SizeOf bunun için bir döndürür.

Bunun nasıl yapılacağına dair herhangi bir öneri çok takdir edilecektir.

cevap

7

Ben böyle bir şey yapmak istiyorum düşünüyorum: Sonra

şu şekildedir:

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public class SOME_BYTES 
    { 
     [MarshalAs(UnmanagedType.ByValArray, SizeConst=320)] 
     public byte[] b; 
    } 

Bunu initialize ediyorum data.b [] öğesini doldurabilir ve verilerin gönderilmesini sağlamak için sıralamayı kullanabilirsiniz. MarshalAs özniteliği, marşaliye, verileri sıralarken ne boyutta bir arabellek kullanılacağını söyler.

Bu tür bir şeyi yapmak için güvenli olmayan sabit anahtar sözcüğünü kullanmanız gerekmez ve bundan kaçınmanızı kesinlikle öneririz.

+0

Bu hile yapar. Ben kesinlikle bu InteropServices/MarshallAs hizmet yelpazesi hakkında daha fazla okumak zorundayım çünkü bu proje için koltukaltı benim koltukaltı kadar olacağım gibi görünüyor! – user316117

11

Bir sabit boyutlu dizi kullanabilirsiniz:

unsafe struct SomeBytes { 
    public fixed byte b[320]; 
} 
+1

Eh, bu işe yarıyor gibi görünüyor. "Güvensiz" anahtar kelimesine aşina değildim ve bunu kullanmak için projenin yapı özellikleri için "/ güvensiz" ile inşa etmeniz gerektiğini öğrendim. Bu da sınırlar kontrolünü ve belki de tüm program için diğer şeyleri kapatıyor. Yazdığım ve tam olarak anladığım birkaç yöntem için güvensiz moda girmem gereken bir şey var, ama neredeyse 200K'lık kod satırı olan bir program için "/ güvensiz" kurma konusunda biraz gerginim. Diğer insanlar ne düşünüyor? – user316117

+4

@ user316117/unsafe, güvenli olmayan kodun kullanılmasına izin vermesi dışında projedeki hiçbir şeyi değiştirmez. – ghord

12

Sen güvensiz kod ile iyi olduğundan eğer fixed size buffers kullanın ve bir yapı içine sınıfınızı değiştirerek yapabilirsiniz: Şahsen

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public unsafe struct SomeBytes 
{ 
    public fixed byte MessageData[320]; 
} 

Ben Mümkünse tüm bunları önlemek için 'u deneyin. Verileri ağ üzerinden gönderiyorsanız, neden "yönetilmeyen alana gitmeniz" gerekiyor? Bu ihtiyacı bir şekilde giderebilir misin? (Belki de temel - ama sorunuza gelen açık değil.)

+0

Makineye gönderilebilecek 50'den fazla farklı mesaj var ve her mesaj farklı tipteki bireysel yapılardan çalışma zamanında birleştiriliyor.Bir yapıda bir çift, bir 16 bitlik bir uint, bir kaç bayt vb. Olabilir. Yönetilmeyen alanın içine girilmesi, fotokopi ile kopyalama işlemini kolaylaştırır. Daha fazla ayrıntı için bu http://stackoverflow.com/questions/14485653/copying-different-structs-to-byte-arrays hakkındaki daha önceki soruma bakın. – user316117

+0

@ user316117: Baytil bir kopya yapmak, * kısa * dönemde işleri daha basit hale getirme eğilimindedir, ancak deneyimimdeki uzun vadede farklı biçimlere geçiş yapmayı çok zorlaştırır. Genellikle serileştirme için daha esnek bir yaklaşımı tercih ederim, ör. protokol arabellekleri. –

+0

https://developers.google.com/protocol-buffers/docs/overview adresindeki protokol arabelleği belgelerine baktım ve iletişim bağlantısının her iki ucunun da protokol hakkında bilgi sahibi olması gerektiği anlaşılıyor. Konuştuğumuz endüstriyel ekipman bir PC değil; Yeni veya farklı bir formatı kabul etmek için programlamanın hiçbir yolu olmayacaktı. Gelecekte yeni ya da farklı formatlara geçmek isteyip istemediklerini yönetim ile tartıştım ve cevap açık bir “hayır” idi. – user316117