Newsgroup: it.comp.programmare.win32
Titolo: Chiamata di funzione in dll con VB

Ho un problemino nell'utilizzare la libreria di invio SMS
con il VB.
Praticamente la libreria funziona bene con i vari compilatori
C/C++ ma in VB, riesco ad inviare solo il primo.
La funzione prende due parametri:
1° - struttura con le info dei messaggi da inviare:
Typedef smsuser
    phone as String ' telefono
    sms   as String ' sms
    forClass as Long ' ritorna un puntatore a memoria
End Type
Inizializzo così:
Dim a(0 to 1) as smsuser
a(0).phone = "numero"
a(0).sms = "Messaggio da inviare"
a(1).phone = vbNullString ' indica il terminatore di invio
2° - numero di thread che devono inviare in parallelo
Quando faccio la chiamata e ritorna, praticamente mi invia solo
l'sms contenuto nel primo elemento.
Declare Function ...(ByRef array as smsuser, ByVal num as long) ...
Chiamata in VB: funzione(a(0), 1)
Da cosa può dipendere???

 
Dal fatto che, dichiarata così, prende un solo oggetto smsuser e, 
richiamata a quel modo, gli passi solo il primo elemento dell'array.
-- 
Valter Minute
(the reply address of this message is invalid,
but you may be able to guess the right one)

 
In realtà quando si usano array di oggetti, la via corretta è questa,
cioè passare il primo elemento dell'array...anche per le API di win32
si usa lo stesso meccanismo!
Anche perchè gli altri modi, non funzionano affatto.

 Anche perchè gli altri modi, non funzionano affatto.
Probabilmente sull'help di VB è spiegato come passare un array a una 
funzione.


 non con un parametro dello stesso tipo degli elementi dell'array.
Si questo è corretto per il linguaggio C/C++;
ma in VB si usa questa tecnica e nella conversione, il primo elemento 
viene convertito in indirizzo...
Almeno così funzionano ed ho utilizzato in passato alcune API di win32
Sull'help di Vb per le declare, non c'è scritto molto...

 
Funzionano perchè passano il parametro per riferimento e non per valore 
(cerca byref e byval nell'help per chiarirti un po' le idee) e 
l'indirizzo del primo valore corrisponde all'indirizzo dell'array, un 
po' come &(a[0]) in C.
Prova a vedere dove sono spiegate le funzioni e gli array. Forse, prima 
di realizzare programmi complessi, è il caso che inizi da un testo sul 
VB che spieghi i meccanismi base del linguaggio.
Se chiedi aiuto nei ng di VB troverai sicuramente gente più preparata 
di me che saprà spiegarti come passare gli array alle funzioni.


 po' come &(a[0]) in C.
E lo so, infatti la dichiarazione prende il Byref, e passando il primo
elemento dell'array, questo viene convertito in indirizzo!

 primo elemento dell'array, questo viene convertito in indirizzo!
Questo è valido solo se richiami funzioni in C e deriva dal fatto che 
il C non fa grossa differenza tra puntatori e array.
In VB non ci sono i puntatori. E questa non mi pare differenza da poco.


 In VB non ci sono i puntatori. E questa non mi pare differenza da poco.
Il problema non è se in VB c'è o non c'è la differenza da te 
evidenziata...la tecnica per far si che nella DLL sia passato
l'indirizzo dell'array di VB è questo, cioè passare il primo elemento!
Infatti quando viene eseguito il ciclo nella DLL non si verifica nessun
errore ed i dati vengono letti correttamente.

 verifica nessun errore ed i dati vengono letti correttamente.
Ma tu non dovevi passare l'array a una funzione VB?


 
Ma scusa fino ad ora sto parlando di API e DLL!
L'esempio da te citato funziona perchè è tutto codice VB,
ma io devo passare un array VB ad una funzione C all'interno
di una DLL...

 Anche perchè gli altri modi, non funzionano affatto.
falso...
c'è un modo semplicissimo che funziona alla grande e che consiste nel
passare un puntatore al contenuto dell'array (e come altro vorresti
fare??).
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Sull'help di Vb per le declare, non c'è scritto molto...
spero che tu il VB sia costretto ad usarlo per motivi di lavoro: non lo
consiglierei al mio peggior nemico (vabbè, forse a lui si... :P).
è mai possibile che il concetto di "puntatore al contenuto di un array"
possa essere confuso con "il primo elemento di un array"? neanche un
puntatore al primo elemento poi, l'elemento stesso...


 di una DLL...
ma LOL :D
spero di non dover **mai** essere costretto a portare a termine un compito
così ingrato... :D


 
Non è come pensi tu...in VB per usare qualsiasi API che utilizzi un 
puntatore ad un array, va fatto in questo modo! Non lo dico io, ma i
libri; ho già utilizzato questa tecnica nel passato è funziona.
Qui nessuno sta confondendo il puntatore ad un array con il primo
elemento di questo!

 
Ok...fammi un esempio allora!

 Da cosa può dipendere???
Da cosa fa la funzione. Da come tratta l'array. Cioè, come fa a 
sapere quanti elementi trattare, probabilmente l'errore sta in 
quel controllo.
Steve. 

 quel controllo.
Magari è qui, non so. La funzione nella libreria non conosce mai
la dimensione dell'array, perchè deve essere un array con terminatore
NULL
smsuser a[] = {
	{"numero", "messaggio"},
	{"altro num", "altro mess"},
	{NULL}
};
Magari in VB questa tecnica non funziona...
Inserendo un log nel ciclo della funzione DLL, effettivamente mi
legge solo il primo elemento, quasi come se dopo l'incremento dell'array
venga trovato il NULL...
mi sa che devo creare un wrapper di questa funzione che accetti anche il
numero di elementi dell'array...esclusivamente per il corretto uso in VB

 NULL
Sì, questo si era capito. Ma se non posti il pezzo della 
funzione dove viene eseguito il ciclo ed il controllo credo sarà 
difficile aiutarti.
Steve. 

 Ok...fammi un esempio allora!
uno? te ne faccio uno si... un milione!!
alcuni esempi nella GDI:
GetBitmapBits, GetDIBColorTable, GetDIBits, SetBitmapBits,
SetDIBColorTable, SetDIBits
Polygon, PolyPolygon
ExtTextOut
GetCharWidth, GetCharWidth32, GetCharWidthFloat
GetGlyphIndices
GetGlyphOutline
GetKerningPairs
GetOutlineTextMetrics
GetTabbedTextExtent
GetTextExtentExPoint
PolyTextOut
TabbedTextOut
PolyBezier, PolyBezierTo
PolyDraw, Polyline, PolylineTo, PolyPolyline
e ne ho saltate tantissime...
e a proposito: qualsiasi API che prenda in ingresso una stringa prende in
ingresso un puntatore al contenuto di un array di TCHAR.


> uno? te ne faccio uno si... un milione!!
Sě, perň:
Visual Basic Concepts - Passing Arrays to a DLL Procedure
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/html/vbconpassingarraystodllprocedure.asp
Steve. 

 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/html/vbconpassingarraystodllprocedure.asp
Grazie...
non so se la gente a volte si impunta per presuzione o stupidita!?!

 Polygon, PolyPolygon
[cut]
beh...forse non mi spiego bene quando scrivo!
NOn ti ho chiesto le API che prendo array come parametri,
ma un esempio di codice VB che usa tali API!
E se lo riesci a far funzionare, è perchè passi il primo
elemento dell'array VB alla funzione API.

 elemento dell'array VB alla funzione API.
ecco perché odio Visual Basic: è mai possibile che si debba far confusione
tra un puntatore al contenuto di un array e il suo primo elemento? neanche
un puntatore al primo elemento, no, l'elemento proprio...
in C è come dire:
int v[5] = {0, 1, 2, 3, 4, 5};
if ((void*)v == (void*)v[0]) {
    // codice che verrà sicuramente eseguito...


 un puntatore al primo elemento, no, l'elemento proprio...
una precisazione: naturalmente quello è *uno* dei motivi per i quali odio
Visual Basic, anzi al limite questo fatto specifico lo accetterei pure
visto che i puntatori in BASIC non li ho mai visti...


 int v[5] = {0, 1, 2, 3, 4, 5};
urgh!!!! O.o'
figura di m...
ecco lo vedi? lo vedi? effetto visual basic... -.-'
ma dimmi te che roba, che roba... -.-'


 }
C'è un motivo: in Visual Basic quando tu definisci
Dim Array() as Byte
non ottieni un *seplice* puntatore ad una zona di memoria (come avviene in 
C) ma ad una struttura che descrive l'array: SAFEARRAY.
Per questo motivo quando devi utilizzare delle API o comunque delle funzioni 
scritte in C che accettano esclusivamente puntatori alla memoria devi 
utilizzare la tecnica di passare l'indirizzo del primo elemento dell'array 
che corrisponde in effetti al puntatore della memoria dove risiedono i dati.
Anche in C puoi comunque gestire i SAFEARRAY (ci sono tutte le funzioni del 
caso), ed è una tecnica che consiglio quando dovete scrivere software misto 
VB / VC e volete che si interfacci senza troppi problemi.

 obsoleto) i puntatori in Visual Basic non esistono nemmeno...
Penso che tutti gli altri mi abbiano capito alla perfezione!
Non sono più un grande sostenitore di questo linguaggio, ma
molti lo criticano perchè evidentemente non lo sanno usare veramente;
fare un semplice form con accesso ai dati, non è tutto quello che
può fare il VB! Ho creato tutti i programmi che faccio anche con
il C, certo con prestazioni più decadenti, ma sempre sono riuscito a
farli, sia ricorrendo alle API che facendoli totalmente in VB!
I puntatori, a differenza di quanto pensi, esistono eccome in VB: 
objptr(), strptr(), AddressOf.
Sono tutte funzioni/operatori che restituiscono puntatori ad oggetti,
ma non molti lo sanno a quanto pare!

 ma non molti lo sanno a quanto pare!
capirai che perdita non saper usare Visual Basic... ma piuttosto spero di
non dover mai essere costretto a usarlo...


capisco perfettamente, ma fermo rimane che in Visual Basic quello che devi
passare alla funzione che vuole l'array è il primo elemento, non un suo
puntatore, quindi esiste quantomeno confusione sui due diversi concetti; e
poi il fatto di non poter controllare esplicitamente gli array "veri"
(cioè gli array come sono implementati in molti altri linguaggi) a me dice
solo che il linguaggio non è potente, anzi è limitato e concettualmente
sballato; a questo aggiungici che il Basic è obsoleto (è stato inventato
quando penso che nessuno avesse idea di quello che avremmo avuto oggi:
multithreading, multiprocessing, programmi divisi in più moduli,
protezione, programmazione a oggetti... ho fatto solo qualche esempio), e
ottieni semplicemente ciò che penso di Visual Basic.
ho capito bene come funziona il sistema per chiamare, da Visual Basic, una
funzione API Win32 o una generica funzione C che vuole un array in
ingresso, volevo solo dire la mia su questo programma, che si riassume
così: se Visual Basic ha della potenza è dovuto alle miriadi di ActiveX e
DLL di ogni genere (anche quelle eventualmente create dal programmatore
finale) necessarie per farci funzionare un qualsiasi programma; più che un
serio tool di programmazione lo considero un'interfaccia di programmazione
e gestione di ActiveX. consiglio di usarlo solo a chi ne ha una buona
esperienza (Dio ve ne scampi) e a chi non sta a cuore ne' la performance
ne' lo spazio complessivamente richiesto dal risultato finale; nell'usarlo
è meglio non confidare nella portabilità del risultato finale su diverse
versioni di Windows (conosco persone che hanno avuto pessime esperienze in
merito), ne' tantomeno in quella dei sorgenti su diverse versioni del
Visual Basic stesso. insomma, lo usi chi deve fare quattro cose fatte in
fretta e fatte male (questa è come la vedo io).


 fretta e fatte male (questa è come la vedo io).
intendiamoci, per fare solo un paio di cose in fretta e senza bisogno di
grande qualità può anche essere utile, eh... è facile e veloce da usare
dopotutto... basta che si sappia con certezza di non dover mai più
riprendere in mano quel sorgente (altrimenti sul futuro Visual Basic .NET
duemilaeboh salteranno fuochi d'artificio come minimo) e possibilmente di
non doverlo portare su versioni di Windows vecchie (o nuove...).


 non dover mai essere costretto a usarlo...
Ma guarda, io amo il C e lo uso sempre quando posso; ma sinceramente 
usare il VB molte volte mi diverte (lo uso quando devo fare cose veloci) 
ed è sempre comodo da un punto di vista del mercato...sarà il 6 o il 
.net, ma sempre VB è! è sempre richiesto è!

 ..net, ma sempre VB è! è sempre richiesto è!
ahimè, vero purtroppo... :(
Dio me ne scampi (sarà l'ennesima volta che lo dico in questo thread).


 non doverlo portare su versioni di Windows vecchie (o nuove...).
Guarda che io volevo solo spiegare le differenze degli array in VB rispetto 
al VC++ , non mi interessa entrare nel merito di cosa sia meglio.

 al VC++ , non mi interessa entrare nel merito di cosa sia meglio.
ok, ti ringrazio


 siano difficili da trovare).
Da come hai risposto in questo thread, non mi sembra proprio...
Comunque...

 un puntatore al primo elemento, no, l'elemento proprio...
Perchè in VB le variabili vengono passate già come riferimento 
(ovvero come puntatore).
-- 
IBM: Ici Beaucoup Merde
News 2000 [v 2.06] / StopDialer / PopDuster - 
http://www.socket2000.com
Akapulce portal: 
http://www.akapulce.net

 Da come hai risposto in questo thread, non mi sembra proprio...
ehm, penso che chiunque potrebbe dire lo stesso di te solo per quello che
ti ho quotato qui sopra


 ti ho quotato qui sopra
Forse non ti è chiara una cosa: c'è una bella differenza tra sapere di 
poter fare un driver in VB, e valutare con quale linguaggio farlo!
Questa quotata da te, ne è l'ennesima prova...

AlterX ha scritto:



oh va bene, perdonami, sono proprio un presuntuoso incompetente e ne ho
dato ampia prova; ora però sono sinceramente incuriosito e vorrei sapere
come è possibile creare un driver in Visual Basic 6, passo passo: allora,
io apro Visual Basic 6 e mi appare la finestrona centrale dove scelgo il
tipo di progetto che voglio creare; poi che faccio?


 tipo di progetto che voglio creare; poi che faccio?
ti consiglio di leggere bene quello che ho scritto; anzi te lo riporto:
il ddk alla fine e come il resto delle librerie (speech SDK, directX
 > SDK, ecc...), quindi non vedo perchč non sia possibile, se sono previste
 > le esportazioni per il VB!
In particolare, l'ultima frase "...se sono previste le esportazioni per 
il VB"
Mi sembra di parlare chiaro!!
Francamente non mi occupo di device driver, ne so *se esistono 
esportazioni* per VB. Quindi se vuoi creare un driver con VB, devi
arrangiarti da solo...
Io non ho detto che con il VB *si puņ* creare un driver.
Forse sono io che non so esprimermi bene :-(

 Io non ho detto che con il VB *si può* creare un driver.
secondo me si.


 di preciso?
Intendevo dire proprio questo prima e come risposta alla tua domanda ora.
Prima dici che VB bla...bla...e ora dici perfettamente quello che ho 
detto io! mah...

 detto io! mah...
prima dico che VB bla bla bla e adesso lo dico ancora: leggi la mia
penultima risposta a Guglielmo Calligaro in questo thread, sostengo ancora
tutto quello che ho detto (e per la verità penso anche che in VB non sia
possibile scrivere drivers, aldilà della performance, della pessima scelta
di linguaggio, ecc.).


 leggi la mia penultima risposta a Guglielmo Calligaro in questo thread
penultima e terzultima.
