Announcement

Collapse
No announcement yet.

Übergabe einer Structure mit Arrays an eine unmanaged DLL

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Übergabe einer Structure mit Arrays an eine unmanaged DLL

    Hallo

    Ich habe ein Problem bei der Übergabe einer Struktur mit Arrays aus VB.NET an eine unmanaged DLL. Funktionen der DLL, die nur Strukturen mit einfachen Variablen benötigen, funktionieren, z.B.

    <PRE>
    Public Structure Simple
    public wert1 as integer
    public wert2 as integer
    end strucure
    </PRE>

    Ich habe die Library sowohl mit einer C++ MFC Applikation und auch einer C++ .Net Applikation getestet, und dort funktioniert alles.

    Im VB.NET habe ich nun alles mögliche ausprobiert, komme aber nicht mehr weiter. ich durchschaue das einfach nicht, wie im VB.NET die Struktur zusammengebaut wird bzw. werden muss.

    ===== Vorgabe unmanaged c++ Eeglib.dll
    <PRE>
    typedef struct
    { int duration;
    char dat[20];
    char name[MAXELEC][8];
    char type[MAXELEC];
    int maxconv[MAXELEC];
    char unit[MAXELEC][4];
    } TCoh3Le;

    typedef int LoadEeg(char *filename,TCoh3Le *header);
    </PRE>


    ===== Code in VB.NET
    '-- Variante 1:
    ' hier kommt Fehlermeldung von der DLL (Memory-Fehler)
    <PRE>
    Public Structure TCoh3Le
    Public duration As Integer
    <VBFixedArray(20)> Public dat() As String
    <VBFixedArray(MAXELEC * 8)> Public name()() As String
    <VBFixedArray(MAXELEC)> Public type() As Byte
    <VBFixedArray(MAXELEC)> Public maxconv() As Integer
    <VBFixedArray(MAXELEC * 4)> Public unit()() As String
    End Structure
    </PRE>

    '-- Variante 2:
    ' hier kommt Fehlermeldung von der DLL (Memory-Fehler)
    <PRE>
    <StructLayout(LayoutKind.Explicit)> _
    'auch ohne StructLayout versucht
    Public Structure TCoh3Le
    <FieldOffset(0)> Public duration As Integer
    <FieldOffset(4)> Public dat() As String
    <FieldOffset(24)> Public name()() As String
    <FieldOffset(24+MAXELEC*8)> Public type() As Byte
    <FieldOffset(24+MAXELEC*9)> Public maxconv() As Integer
    <FieldOffset(24+MAXELEC*10)> Public unit()() As String
    End Structure
    </PRE>

    '-- Variante 3:
    ' hier kommt Fehlermeldung vom Debugger
    ' - Marshaling nicht erlaubt
    <PRE>
    Public Structure TCoh3Le
    Public duration As Integer
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=20)> _
    Public dat() As String
    ......
    End Structure
    </PRE>

    '--- Funktion
    <PRE>
    <DllImport("EegLib.dll", EntryPoint:="#4")> _
    Public Shared Function LoadEeg(ByVal filename As _
    String, ByRef header As TCoh3Le) As Integer
    End Function
    </PRE>

    Wer hätte einen Tip ?

    Danke
    Gerald

  • #2
    Hallo,

    die C++-Struct deklariert ein Char-Array (<i>char dat[20]</i>), daher würde ich in .NET auch ein Char-Array von der richtigen Größe als Ablageplatz nehmen (Char-Storage Size: 2 Bytes; String-Storage Size: 10 Bytes + (2*Länge)).

    Das folgende Beispiel hat beim Datenaustausch Delphi (Win32) --> C# funktioniert:
    <pre>[StructLayout(LayoutKind.Sequential,Pack=0,CharSet= CharSet.Ansi,Size=34)]
    <b>private</b> <b>struct</b> PackedRecNative
    {
    <b>internal</b> Int32 ID;
    <b>internal</b> <b>byte</b> NameLen;
    <font color="#FF0000"><b>[MarshalAs(UnmanagedType.ByValArray,SizeConst=15)]
    internal char[] Name;</b> </font>
    <b>internal</b> <b>sbyte</b> SI;
    <b>internal</b> <b>byte</b> Kat;
    <b>internal</b> <b>byte</b> RemLen;
    [MarshalAs(UnmanagedType.ByValArray,SizeConst=10)]
    <b>internal</b> <b>char</b>[] Rem;
    }
    </pre>
    &#10

    Comment

    Working...
    X