Newsgroup: it.comp.lang.visual-basic
Titolo: [!] Array di strutture e DLL

Come promesso vi posto la mia soluzione.
Non è bellissima ma funziona.
La classe deve esportare un metodo tipo questo:
MyClass.Export(Buffer() As Byte, Optional ByVal From As Long = 1, Optional
ByVal Count As Long = 0)
e
MyClass.Import(...) ' con lo stesso prototipo
Al loro interno basta chiamare le sub che riporto sotto.
Appena fuori dalla chiamata basta chiamare la sub inversa.
Es.
Dim T() as MyStruct
dim b() as byte
Redim T(1 to 20) as MyStruct
' esportazione del type all'esterno della classe
call MyClass.Export(b(), 1, 20)
Call BufferToType(b(), T())
Nota:
- Le sub sotto sono state scritte in modo da usare array con indice
inferiore = 1.
  Occorrerà correggerle per usare LBound() anzichè 1.
- Ho perso tre ore per capire che un array dinamico ha per ogni elemento un
header di
  2 byte per ogni elemento.
- Queste funzionano se il Type è a lunghezza fissa, per cui solo membri
stringa a
  lunghezza fissa e array statici.
Spero di essere stato chiaro :)
Ciao
----------------------------------------------------------------------------
------------
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(Destination As Any, Source As Any, ByVal length As Long)
Public Sub TypeToBuffer(lpEx() As MyStruct, Buffer() As Byte, Optional ByVal
From As Long = 1, Optional ByVal Count As Long = 0)
    Dim u As Long
    Dim e As MyStruct
    ' ------------------------
    '  Defaults limits
    ' ------------------------
    u = UBound(lpEx())
    If (From <= 0) Then From = 1
    If (From > u) Then From = u
    If (Count <= 0) Then Count = u
    If (Count > u) Then Count = u
    ' ------------------------
    '  Copy Elements
    ' ------------------------
    If (Count > 0) Then
        ' ci sono 2 byte in più per ogni elemento dell'array
        u = Count * (Len(e) + 2)
        ReDim Buffer(1 To u)
        Call CopyMemory(Buffer((From - 1) * (Len(e) + 2) + 1), lpEx(From),
u)
    Else
        ReDim Buffer(0 To 0)
    End If
End Sub
Public Sub BufferToType(Buffer() As Byte, lpEx() As MyStruct, Optional ByVal
From As Long = 1, Optional ByVal Count As Long = 0)
    Dim u As Long
    Dim e As MyStruct
    ' ------------------------
    '  Defaults limits
    ' ------------------------
    u = UBound(Buffer) \ (Len(e) + 2)
    If (From <= 0) Then From = 1
    If (From > u) Then From = u
    If (Count <= 0) Then Count = u
    If (Count > u) Then Count = u
    ' ------------------------
    '  Copy Elements
    ' ------------------------
    If (Count > 0) Then
        ' ci sono 2 byte in più per ogni elemento dell'array
        u = Count * (Len(e) + 2)
        ReDim lpEx(1 To Count)
        Call CopyMemory(lpEx(From), Buffer((From - 1) * (Len(e) + 2) + 1),
u)
    Else
        ReDim p_Ex(0 To 0)
    End If
End Sub

 Non è bellissima ma funziona.
[SNIP]
Vedi la mia risposta nell'altro thread (non splittiamo ulteriormente, pliz
;-) )
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown


Veramente questo post è stato inviato PRIMA della tua risposta.
Poi una soluzione se richiesta da più parti è buona norma darla in un nuovo
thread, in modo che sia leggibile.
Detto questo, ammetto che funziona.
Ora mi si spieghi perchè, anche dopo tutte le discussioni passate.
Ciao

 Ora mi si spieghi perchè, anche dopo tutte le discussioni passate.
Intendi perche' funziona?
e' semplicemente una delle novita' di VB6, e' menzionata nella
documentazione sotto 'Novita' di Visual Basic\Novità relative alle
funzionalità del linguaggio'.
Bisogna poi prestare attenzione al messaggio di errore che tipicamente
compare provando per la prima volta, che nella versione italiana e'
particolarmente contorto:
"Solo i tipi pubblici definiti dall'utente definiti in moduli di oggetto
pubblici possono essere utilizzati come parametri o tipi restituiti per
routine pubbliche di moduli di classe o come campi di tipi pubblici definiti
dall'utente"
che nella sostanza vuol dire: funziona purche' il Type sia dichiarato Public
in una classe, esattamente come succede per gli Enum.
Comunque ci sono casi in cui sembrano esserci dei problemi; per esempio un
Type pubblico in uno User Control credo faccia casino... non so se ci sono
altre situazioni analoghe perche' onestamente e' un sistema che in pratica
non uso quasi mai.
