Newsgroup: it.comp.lang.visual-basic
Titolo: struttura con matrice e API

Ciao a tutti,
sto utilizzando una dll con una serie di funzioni. Un gruppo di queste
funzioni sono identiche, gli argomenti sono un Integer ed una
struttura dati e ritornano un Integer.
Le ho utilizzate con successo ad eccezzione di una che mi ritorna
INVALID INDEX.
L'unica differenza che riesco a trovare è nella struttura passata,
poichè incorpora una matrice.
Probabilmente sto sbagliando la dichiarazione del Type per cui l'API
(fatta in C++) non capisce il tipo di dato.
Allego la dichiarazione e la chiamata della funzione in C++. Poi vi
faccio vedere come ho tradotto in VB.
// COME UTILIZZARE LA FUNZIONE IN C++ //
// declaration: 
typedef CHAR ConNameStr[11]; 
typedef CHAR Array10[11]; 
typedef Array10 LegType[5]; 
typedef struct { 
   ConNameStr ContractName; 
   LegType Leg[2]; 
} ContractStruct, FAR *ContractStructPtr; 
typedef INT (WINAPI * lp_ptGetContract)(INT Index, ContractStructPtr
Contract);
// function call 
... 
int nLoop; 
ContractStruct contract; 
ptGetContract(nLoop,&contract) 
... 
//////////////////
Traduzione in VB
'''''''''''''''''
' declaration 
Type ContractStruct 
  ContractName As String * 11 
  Leg(1, 4) As String * 11 'Ho provato anche con (2, 5) 
End Type 
Public Declare Function ptGetContract Lib "demoapi.dll" (ByVal Index
As Integer, ByRef Contract As ContractStruct) As Integer
' function call 
Dim nIdx as Integer 
Dim Contract as ContractStruct 
Contract.ContractName = Space(11) ' inizializzo le stringhe per
passarle alla
funzione in c++ 
Contract.Leg(0, 0) = Space(11) 
Contract.Leg(0, 1) = Space(11) 
Contract.Leg(0, 2) = Space(11) ' ...inzializzo tutta la matrice 
n=ptGetContract(nIdx, Contract) 
' n ritorna INVALID INDEX ma sono sicuro che nIdx è corretto
Vi ringrazio per l'interessamento.
William

 ' n ritorna INVALID INDEX ma sono sicuro che nIdx è corretto
ciao
CCCP++Mario


Ciao Mario,
intanto grazie per il tuo aiuto.
Dalla mia documentazione il tipo char dovrebbe esser di 1 byte quindi
ansi.
Hai scritto che avresti dichiarato diversamente i tipi string, magari
con un array di char. E' più corretto?
Questo tipo di ragguagli mi fanno comodo perchè il mio progetto è poco
stabile e nel mio vbp utilizzo "pesantemente" la dll.
William

 ansi.
OK, char per quel che riguarda la CPP-Side.  Per la VB-Side invece il tipo
predefinito di stringa è unicode (2 byte) e già questo è una causa di non
corrispondenza delle dimensioni.
In VB sono state messe funzioni di conversione di stringhe da / a unicode,
ma sfortunatamente nessun dichiaratore specifico per gli UDT.
Di conseguenza se vuoi conoscere con certezza lo spazio riservato, ti
consiglio di inglobare nell'UDT dei begli array statici di tipo BYTE (char
in VB non esiste)
al limite crea un involucro fittizio col solo scopo di incapsulare l'array,
tipo
Type StringaANSI_10
      Dati(0 to 9) As Byte
End Type
Type StringaANSI_16
      Dati(0 to 15) As Byte
End Type
e poi li usi al posto di dire   As String * 10,   As String * 16
Le matrici (ma solo statiche) credo siano allocate nella struttura senza
alcun genere di descrittore o overspace, eccetto forse il padding
Ecco, un'unica accortezza potrebbe riguardare il layout in memoria effettivo
(allineamento dei membri).
Su disco gli UDT sono sempre scritti in modo compatto, senza vuoti, ma in
memoria le variabili potrebbero essere allineati ad indirizzi multipli di 32
bit (4 byte), ciò che può creare incoerenze nel mappare dati apparentemente
identici da linguaggi diversi che usino convenzioni di layout in memoria
diversi.
Se ti è possibile, controlla tramite len (in VB) e sizeof (in CPP)
l'effettivo consumo di memoria.
Inoltre tramite  VarPtr (in VB) e & (in CPP) controlla che gli offset dei
membri dati delle strutture corrispondano effettivamente a quanto ti aspetti
: se hai più di una matrice di byte in numero dispari, temo che questa
corrispondenza non sia garantita.
ciao
CCCP++Mario
