Newsgroup: it.comp.lang.vo-clipper
Titolo: Importare una DLL con Classe

Nel caso di una DLL che contenga delle funzioni si usa:
     LoadLibrary(String2Psz("MiaDll.DLL"))
per caricare la libreria dinamica, e:
_DLL FUNCTION MiaFunzione(oWin AS OBJECT) AS ARRAY PASCAL:MIADLL.MiaFunzione
per definire l'interfaccia con la funzione contenuta nella DLL.
Adesso ho provato a fare una DLL costituita da una sola classe e alcuni
metodi associati ad essa.
Suppongo che la libreria si carichi allo stesso modo, ma come si fa a
definire l'interfaccia e quindi ad instanziare la classe contenuta nella DLL
?
Dimenticavo, Vorrei che la DLL possa essere utilizzata da altri linguaggi,
devo adottare delle precauzioni ?

devo adottare delle precauzioni ?
Credo si possano condividere *solo* chiamate a funzioni di una DLL,
mentre non si possono utilizzare classi VO dall'esterno.
HTH
===============================================
Antonello Negrone - Biella - Italy
anto...@anc-software.it
www.anc-software.it

mentre non si possono utilizzare classi VO dall'esterno.
Frase da precisare:
"Dall'esterno" inteso come "da altri linguaggi"
Saluti


 devo adottare delle precauzioni ?
Uhm... non credo che una DLL generica possa contenere classi
istanziabili dall'esterno. Per questo esistono gli oggetti COM.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg


Ciao Claudio, in merito all'utilizzo delle DLL caricate dinamicamente non ho
suggerimenti da darti, ma ti riporto quella che per me č stata una brutta
esperienza. Tempo fa avevo spostato in una DLL diverse funzioni di una mia
applicazione. Purtroppo una di quelle funzioni veniva richiamata all'interno
di un loop. Per circa 8-9000 cicli non vi erano problemi ma dopo il
programma si bloccava dandomi il famigerato errore 5333.
Senza tanto indagare, ho subito lasciato perdere la mia bella DLL ed ho
riportato tutte le funzioni all'interno dell'applicazione. Dopo di che non
ho piů avuto 5333 di sorta.
Probabilmente mi sono arreso troppo presto, ma il codice nella DLL mi
sembrava scritto comunque correttamente.
Tu dove ti sei documentato in merito alle metodologie da utilizzare con VO
per l'uso delle DLL? Io avevo guardato solamente le API di Windows.
Saluti.
Roberto Cordini

 mentre non si possono utilizzare classi VO dall'esterno.
Anche le funzioni hanno una limitazione.
Occorre che siano definite con convenzione di chiamata di tipo Pascal
altrimenti non funzionano . In piů non possono essere utilizzati parametri
di tipologia Clipper:
es:
Function Pippo( cStringa )
Return .T.
oppure
Function Pluto( cStringa AS STRING ) AS LOGIC STRICT
Return TRUE
non possono essere usati da altri linguaggi. Mentre il seguente es. si:
Function Paperino( pszStringa AS PSZ) AS LONGINT PASCAL
Return 0L
In pratica i parametri non possono essere di tipo dinamici ( Come il
Clipper )
Per quanto riguarda le Classi non ti so dire. Forse le classi s'implementano
come OLE da altri linguaggi. Comunque a proposito non ho conoscenze adeguate
per risponderti esaurientemente.
Anche se mi pare di aver letto da qualche parte che in teoria si possono
utilizzare le classi del C++ in sostituzione delle classi Gui del VO. Se
cosi' e' allora potrebbe essere possibile fare altrettanto con altri
linguaggi utilizzando classi VO.
In futuro con la piattaforma .net di microsoft non ci dovrebbero essere piů
problemi di questo tipo ( sara' ma il rovescio della medaglia non vorrei
vederla).
Ciao,
       Fabrizio Malaguti


 >mentre non si possono condividere classi VO.
- Qualcuno può confermare che le classi presenti in una DLL scritta in VO
possano essere condivise solo da programmi scritti in VO ?
- Se no, ci sono delle limitazioni ?
- E per quanto riguarda le funzioni presenti nelle DLL scritte in VO, quali
precauzioni è necessario adottare perché altri linguaggi possano
condividerle ?
Buon lavoro a tutti
Claudio Carletta

 ha scritto nel messaggio
news:wWAf9.79589$ub2.1...@news1.tin.it...


 ho più avuto 5333 di sorta.


 sembrava scritto comunque correttamente.
Forse stavi semplicemente caricando e scaricando la DLL ad ogni
iterazione del ciclo. Puň essere? Tieni presente che questo dovrebbe
essere il comportamento di default per le funzioni dichiarate da DLL
(almeno in Clipper/Fivewin č cosě e mi sembra di aver visto che in VO
sia molto simile). In casi come questi si deve invece procedere in modo
diverso. Si carica la DLL una sola volta, si utilizzano le funzioni al
suo interno e alla fine si rilascia. Purtroppo non ti so aiutare su come
si faccia in VO.


 utilizzare le classi del C++ in sostituzione delle classi Gui del VO.
Dato che il C++ in sé non offre alcun concetto di GUI, dovresti
precisare di quali classi stai parlando. Forse delle MFC oppure WFC
oppure? Tieni presente che nessuna di queste fanno parte del C++ ma sono
solo librerie di classi esterne al linguaggio.


 VO...
Non è il mio caso (VO ---> VO)
Ciao e grazie.
Roberto Cordini


Mi riferivo alle MFC.
Si e' vero che le MFC sono esterne al linguaggio C++. Se non erro pero'
dovrebbero essere delle classi create con il C++ allo scopo di creare
programmi con interfaccia utente GUI programmando con la logica degli
oggetti anziche' una logica standard di programmazione strutturata ( come un
programma C per intenderci ).
La stessa cosa e' stata fatta col VO, nulla vieta di utilizzare direttamente
le API di window e utilizzare la sintassi Clipper ( con l'aggiunta della
tipizzazione delle variabili ), pero' la logica degli oggetti semplifica
notevolmente la gestione degli eventi di window (almeno per me), e non solo.
L'articolo che avevo letto (non ricordo piu' in che rivista o manuale)
spiegava appunto che si potevano utilizzare le MFC in posto dell'interfaccia
GUI del VO ( le classi sono sviluppate dalla CA ). In alternativa è
possibile anche utilizzare le classi GUI  della DataPro, Inc ( le famose
CLASSMATE utilizzate nell'ultima versione di REPORT PRO creato dalla stessa
ditta).
La differenza è che mentre le MFC dovrebbero essere scritte in C++ , queste
ultime sono scritte con sintassi VO 2.5x ( pertanto non funzionano con VO
2.0).
Non conosco le WFC. Cosa sono?
Ciao,
       Fabrizio Malaguti


 di tale classe?
Certo, ad esempio :
MiaFunzione(pDBS AS PTR)
LOCAL oDBS AS DBSERVER
oDBS:=OBJECT(_CAST,pDBS)
oDBS:FIELDGET(#PIPPO)
.....
Unico consiglio che posso darti e quello di valutare bene se ti serve
realmente una DLL dinamica, "lincata" a runtime,  piuttosto che una DLL
classica "lincata" in fase di compilazione ....
Ciao, Marco

 Non conosco le WFC. Cosa sono?
Windows Foundation Classes (neanche queste recentissime, ormai hanno
qualche anno). Non ti so dire di piů tranne il fatto che, per sentito
dire, dovrebbero essere molto piů OO e finalmente ben fatte rispetto
alle MFC.


 classica "lincata" in fase di compilazione ....
Una DLL è *per definizione* linkata a runtime.


 classica "lincata" in fase di compilazione ....
A questo proposito ho fatto delle prove. Il caricamento dinamico di una DLL
si ottiene con LoadLibrary(...) ma poi mi sembra che l'accesso alle singole
funzioni contenute nella DLL debba avvenire utilizzando la funzione
PCALL(...). Mettere nell'eseguibile sia la LoadLibrary() che i prototipi
delle funzioni con la sintassi _DLL Function ..... è ridondante in quanto
eliminando il LoadLibrary() tutto funziona (almeno per un pò) regolarmente.
Ciao e grazie per le risposte.
Roberto Cordini

 eliminando il LoadLibrary() tutto funziona (almeno per un pò) regolarmente.
Però in questo modo, probabilmente, stai caricando e scaricando la DLL
ad ogni chiamata alla funzione.


 alle MFC.
Ok. Comunque penso che il futuro non sia roseo; vedi la piattaforma .Net di
Microsoft e probabilmente il restyling delle MFC
Ciao,
       Fabrizio Malaguti


 Microsoft e probabilmente il restyling delle MFC
Infatti. Per esperienza so che ogni volta che la MS propone
"innovazioni", per lei sono montagne di soldi in piů e per noi poveri
programmatori sono cavoli amari (ore di duro lavoro gratis per
aggiornarci e per combattere poi i nuovi bugs...).


 ha scritto nel
messaggio news:3D7F47E2...@emagsoftware.it...


Robby e' proprio questo il problema....
Quando passi un Real8 vo in realta' passa un PTR che punta all'indirizzo che
contiene il tuo bel numero....
Lo standard delle DLL non prevede un tipo di dato REAL8 ma VO lo converte
automaticamente in PTR in fase di PCALL.
Il guaio e' che quando il tuo bel REAL8 arriva alla funzione contenuta nella
DLL ci sono buone possibilita' che il GarbageCollector di VO ne abbia
modificato l'indirizzo di memoria. La stessa cosa accade per il valore di
ritorno e forse in maniera piu' pesante.
Ciao, Marco
"Robby" <roberto...@NOXSPAMiol.it> ha scritto nel messaggio
news:alnhpp$a21$1...@zamboni.dsnet.it...


 ritorno e forse in maniera piu' pesante.
Aspetta un secondo: mi pare molto molto strano che possa cambiare
l'indirizzo di memoria di una variabile durante il suo tempo di vita.
Sei proprio sicuro?


 Io intendevo dire "caricata" a runtime ......
Sě, il termine č *molto* infelice. :-) Un caricamento č infatti
possibile solo a runtime. Non mi pare abbia senso parlare di caricamento
a compile time. Comunque, sono perfettamente d'accordo con te che le DLL
č preferibile caricarle appena servono e rilasciarle appena non servono
piů. Peraltro, questo č un criterio che andrebbe adottato qualunque sia
il tipo di risorsa utilizzata (un file aperto, un'icona, un bitmap, un
font, memoria allocata dinamicamente, etc.).


 alle MFC.
Di che sono? di MS?
Per C++ c'e' una libreria free che si chiama wxWindows, si trova su
http://www.wxwindows.org/
 ed ha il vantaggio di essere multi piattaforma
Win, Linux e Mac. Se si riuscisse ad interfacciare ad Harbour il gioco
sarebbe fatto.
Ciao...
Claudio Driussi
http://www.swit.net/csoft
mailto:
cldr...@swit.net

 automatico. 
Tutto sommato mi sembra un po' una cavolata, non credo serva a molto avere piu'
finestre sincronizzate.
Una cosa bella invece c'e l'ha Xbase++ ed e' la facilita' con cui si gestisce
il multithreading ed ogni thread ha una workspace a parte, facendo girare
finestre
diverse su thread diversi si possono avere gestione dati completamente
indipendenti,
e' come avere una multiutenza nella stessa applicazione.


 sarebbe fatto.
Sě, ne avevo sentito parlare. Si vedrŕ...


 e' come avere una multiutenza nella stessa applicazione.
Veramente questa non mi sembra una grossa novità. Per qualsiasi
applicazione Windows (almeno da W31 in poi) ogni finestra e ogni dialog
non modale sono, in pratica, applicazioni diverse che possono andare
avanti indipendentemente.


 ha scritto nel
messaggio news:3D8044A3...@emagsoftware.it...


 e' come avere una multiutenza nella stessa applicazione.
Non so come si gestisce il multithead in Xbase++; In VO 2.5 è semplicissimo.
Ciao,
       Fabrizio Malaguti


 EMG


vederla).
In futuro ;-)
Attualmente trovo che la piattaforma .NET sia troppo pesante. Ho visto
alcune applicazioni scritte in Visual Basic.NET che aveva dei tempi di
risposta millenari :-|||
Ciao
===============================================
Antonello Negrone - Biella - Italy
anto...@anc-software.it
www.anc-software.it

[...]
Beh, dipende...
Questa funzionalità permette, dove serve, di associare un alias
(workspace) a più oggetti client (datawindow, databrowser ecc) i quali
ricevono tutti i messaggi di notifica dal DbServer.
Ad esempio, in caso di spostamento del puntatore al record, si possono
aggiornare automaticamente, oppure si possono opporre allo spostamento
stesso (vedere messaggio NOTIFYINTENTTOMOVE)
Se poi serve scorrere il DBF senza riflettere gli spostamenti verso
il/i client, basta richiamare :SuspendNotification().
Questo per quanto riguarda la struttura di queste classi.
Per quanto riguarda il contenuto (codice sorgente), le classmate sono
(credo) più ordinate e pulite.


e' come avere una multiutenza nella stessa applicazione.
Ecco purtroppo un grosso limite degli RDD di VO. Il fatto di non
essere, come si dice, thread-safe.
Domanda: xBase++ utilizza RDD stile clipper ho ha un motore tipo BDE?


 (credo) più ordinate e pulite.
Si. Io ho i sorgenti sia delle GUI del VO ( VO 2.5 SDK ), che delle
CLASSMATE.
Praticamente quest'ultime sono un quarto di quelle del VO. La motivazione è
che è stata tolta tutta la gestione delle notifiche. E' tutta questa
gestione che fa perdere un tempo infinito. Per il resto sono praticamente
identiche; l'unica differenza è che le CLASSMATE hanno metodi tipizzati e il
compiler pragma:
   ~"ONLYEARLY+"
     ........
   ~"ONLYEARLY-"
Ciao,
       Fabrizio Malaguti
P.S.
    Ho dovuto cancellare una parte di testo precedente perche' non riuscivo
ad inviarlo; mi dava un errore mi diceva che dovevo inserire piu nuovo testo
rispetto al vecchio!! Tu sai cosa significa e dove occorre intervenire?


rispetto al vecchio!! Tu sai cosa significa e dove occorre intervenire?
puo' essere che il tuo NG reader abbia un limite di righe quotate per
messaggio. 
Avevo riscontrato anch'io un simile problema (uso FreeAgent) e l'ho
risolto alzando il limite. Solo che non mi ricordo + dov'è :-(
Cmq, a mio avviso, è sempre meglio riportare poche righe, ma che
rendano un po' il senso del discorso.


 rendano un po' il senso del discorso.
Si. Solo che ultimamente mi tocca togliere troppi pezzi.
Ciao,
       Fabrizio Malaguti


 spesso alcuni puntatori.
Non mi pare possibile che un garbage collector possa in qualche modo
toccare memoria correntemente utilizzata. Da quello che sapevo io, i
garbage collectors riorganizzano la memoria rilasciata, appunto chiamata
"garbage", non quella attualmente in uso. Lo scopo può essere duplice:
restituire la memoria libera allo heap e riorganizzare lo stesso per
ridurre la frammentazione. Il primo è sicuro, il secondo è opzionale ma
desiderabile.


desiderabile.
Credo che in certi casi il GC di VO non sia in grado di determinare se
un indirizzo di memoria sia in uso o meno.
In alcuni casi ho risolto a problemi simili utilizzando
DynLock()/DynUnlock().
Con queste funzioni si puo' interrompere/riprendere l'attività del GC.
Controindicazione: la memoria dinamica cresce molto velocemente, a
meno di utilizzare dati allocati staticamente.


 risposta millenari :-|||
Io spero tanto che resti così. Ma so che la speranza è vana. Verranno
incontro alla MS i produttori hardware che tireranno fuori
all'improvviso, come per magia, i velocissimi processori di prossima
generazione. Ormai è una storia trita e ritrita (e comincia a darmi la
nausea...).


 un indirizzo di memoria sia in uso o meno.
Impossibile. Come potrebbe allora funzionare? Un garbage collector (alla
lettera "collettore di rifiuti") serve proprio a raccogliere le zone di
memoria non piů utilizzate ma rimaste, per cosě dire, "appese" e
restituirle allo heap (memoria disponibile, organizzata a blocchi, dalla
quale si attinge quando serve memoria dinamicamente allocata). A meno
che il concetto VO di garbage collector sia diverso...


che il concetto VO di garbage collector sia diverso...
Non credo che il concetto di GC in VO sia diverso. Pero', da
esperienza diretta, il GC di VO ha dei problemi di questo genere.
Anzi, ora mi viene in mente che non č un problema irrisolvibile.
Utilizzando la funzione RegisterKid() si istruisce il GC di mantenere
valido un puntatore altrimenti non piu' valido dopo una collection.
Ecco quanto riportato dall'help:
------------------------------------------------------------
REGISTERKID
Purpose
Register a dynamic object for update after a garbage collection.
Syntax
RegisterKid(<ptrKid>, <dwCount>, <lItem>) ---> VOID
Arguments
<ptrKid>	A pointer to a dynamic object you want to register.
<dwCount>	The number of consecutive objects to register.  The
objects may be USUALs or typed dynamic objects (strings, floats, class
objects, or arrays.) 
<lItem>	Determines whether registered objects are polymorphic: TRUE
specifies USUAL and FALSE specifies typed.
Description
RegisterKid() ensures that dynamic objects are preserved after a
garbage collection.  Dynamic objects are subject to garbage collection
and their pointers become invalid after a collection.  However, if the
pointer is registered, it is automatically updated and remains valid
after a collection.
[...]


 Domanda: xBase++ utilizza RDD stile clipper ho ha un motore tipo BDE?
Ha una funzionalita' simile agli RDD, loro li chiamano DBE, puoi mischiare
a piacimento indici e DBF di tipo diverso il motore e' contenuto in alcune DLL.
Ad esempio:
PROCEDURE dbeSys()
  DbeLoad( "DBFDBE", .T.)
  DbeLoad( "NTXDBE",.T.)
  DbeBuild( "DBFNTX", "DBFDBE", "NTXDBE" )
  DbeLoad( "FOXDBE", .T.)
  DbeLoad( "CDXDBE",.T.)
  DbeBuild( "FOXCDX", "FOXDBE", "CDXDBE" )
  DbeBuild( "DBFCDX", "DBFDBE", "CDXDBE" )
  DbeSetDefault( "DBFCDX" )
RETURN


 avanti indipendentemente.
Non proprio, e' vero che ogni finestra riceve i propri messaggi dalla
coda, ma gli spazi di indirizzamento sono gli stessi.
Con Xbase++ le variabili public sono visibili in tutta l'applicazione
mentre le variabili private, il workspace dei DBF e le impostazioni tipo
SET EXACT, SET DATE TO ecc... sono visibili solo all'interno del thread 
corrente, questo io lo trovo comodo per non avere conflitti di alias di
database ed aprire piu' finestre contemporaneamente, poi magari ci sono
altre cose che non mi piacciono tanto, ma questo penso che valga per ogni
tool di sviluppo.


mentre le variabili private, il workspace dei DBF e le impostazioni tipo
quindi xBase++ gestisce in automatico anche l'accesso contemporaneo a
variabili public da thread diversi?
Pero'!


 valido un puntatore altrimenti non piu' valido dopo una collection.
Evidentemente sono io che non ne so abbastanza di garbage collection...
:-(


 tool di sviluppo.
Sicuramente. Comunque ma me, più che del tool, non mi piacciono alcuni
*miei* modi attuali di lavorare. Negli anni uno cerca continuamente di
migliorarsi ma si accorge che lo spazio per il miglioramento, invece di
ridursi, quasi quasi si allarga. Nonostante la mia produttività sia
abbastanza alta, vedo che perdo ancora troppo tempo in cose come il
disegno delle maschere (checché se ne dica, nei programmi DOS era molto
più rapido), le stampe (non sono soddisfatto completamente né della
tecnica "free-form" né di quella visuale - forse dovrei scrivermi uno
strumento personalizzato che sia una via di mezzo tra le due), il
riutilizzo (uso troppo il copia/incolla e non abbastanza la
fattorizzazione e la OOP).
Il problema è che risulta molto difficile capire dove migliorare se si
ragiona in astratto, mentre durante lo sviluppo di un progetto è molto
più facile accorgersi dei punti "critici" ma non c'è normalmente il
tempo di interessarsene...


:-(
Personalmente lavorando con clipper (e con Visual Basic) non mi ero
mai posto il problema del GC..
Con VO invece ci si scontra di frequente con questo inquilino, lo si
voglia o no :-)


 voglia o no :-)
Forse perché si è cercato di fondere due filosofie inconciliabili? :-)


Forse perché si è cercato di fondere due filosofie inconciliabili? :-)
Se ti riferisci a "efficienza" e "semplicità"......forse si :-)


 meno di utilizzare dati allocati staticamente.
Ciao Antonello. Mi inserisco nella vostra discussione in merito al GC.
Probabilmente questo benedetto GC avrà anche dei problemi ma non posso
pensare che non sia in grado di determinare se un indirizzo di memoria sia
in uso o meno prima di liberare spazio nello heap. Se fosse così nessuna
applicazione VO anche se testata potrebbe essere considerata affidabile
soprattutto nel caso in cui svolgesse dei calcoli intensivi ed in base ai
risultati ottenuti si dovessero prendere delle decisioni importanti. Devo
purtroppo dire che più uso VO e meno mi sembra di conoscerlo (soprattutto
leggendo i commenti di quelli tra noi più esperti) ! Un normale
programmatore di gestionali come me (pienamente nel target di VO), non penso
si dovrebbe preoccupare di come viene o non viene gestita la memoria a basso
livello dal GC e si dovrebbe poter fidare quasi ciecamente del proprio
ambiente di sviluppo. Spero che la versione 2.6 il cui rilascio è slittato
di circa un mese (e della cui gestazione non si riesce a sapere niente),
risolva queste problematiche da iniziati.
Roberto Cordini

 Se ti riferisci a "efficienza" e "semplicità"......forse si :-)
Come ha appena scritto Roberto, non mi pare che si possa considerare
"semplicità" il doversi preoccupare di quello che fa il GC. Non mi
sembra di conoscere nessun altro strumento di programmazione che
richieda questo. O il GC non c'è proprio (come in C e C++) oppure, se
c'è, (come in Clipper e Visual Basic) lavora in modo completamente
trasparente. Punto.


[...]
Purtroppo la gestione della memoria di VO funziona cosě. 
Da esperienza, quando scrivo un loop "stretto"  (tralasciando il
discorso delle DLL) mi preoccupo di richiamare CollectForced() (forza
il GC) ogni tot cicli, altrimenti, non intervenendo automaticamente,
causerebbe la saturazione della memoria dinamica, con la conseguenza
di un ACCESS VIOLATION.
VO mette a disposizione gli strumenti (DynSize, Collect, ecc.), pero'
sono d'accordo con te quando dici che uno sviluppatore di gestionali
non dovrebbe preoccuparsi della gestione di memoria.
Per il futuro (2.6) non credo ci siano rivoluzioni in questo senso, o
per lo meno, non mi pare di averne lette.
Ciao


 strumento personalizzato che sia una via di mezzo tra le due), 
Io ho trovato un motore free in Delphi e l'ho adattato ed interfacciato
a Xbase++, con poche modifiche si puo' adattare anche a Clipper o a VO,
non trovo mai il tempo per documentarlo un po e metterlo in rete, la libreria
originale si trova su: 
http://mrhru.otts.ru/
 , cerchero' di darmi una mossa 
e metterelo a disposizione. Ha qualche baco, ma per certi versi e' la
migliore delle soluzioni possibili.


 variabili public da thread diversi?
E' uno dei suoi punti di forza.


 per lo meno, non mi pare di averne lette.
Purtroppo sono di questo parere anch'io. Brian probabilmente stà facendo un
buon lavoro e sarà sicuramente troppo impegnato a coordinare il team di
sviluppo (fuori i nomi) per renderci partecipi dello stato di avanzamento
del progetto. Non so voi ma io sono molto curioso e sono impaziente di
saperne di più. Tra l'altro speravo che dopo la settimana di black out del
sito 
www.cavo.com
,  sarebbe stato messo on line qualcosa di nuovo invece
eccolo li spoglio ed immutabile come sempre. Però la data del giorno è
sempre aggiornata :-)
Ciao.
Roberto Cordini

[...]
già, speriamo bene :-)
ciao


 .......
Questo l'ho capito. Purtroppo mi sono imbattuto nell'errore 5333 dopo un
certo numero di chiamate ad una data funzione contenuta in una DLL che avevo
scritto in VO. In pratica mi è stato detto che non posso usare i tipi di
dato di VO ma devo usare i puntatori. Io passavo dei Real8, li elaboravo
nella funzione e restituivo il risultato sempre come Real8.
E` qui che casca l'asino. Non so come passare i parametri alla funzione,
come utilizzarli all'interno della stessa (probabilmente vanno convertiti
con il _Cast) e poi come ritornare il risultato al codice chiamante.
Scusa se è poco!
Ciao.
Roberto Cordini

Scusa se è poco!
Nessun problema ;-)


 migliore delle soluzioni possibili.
Gli darò uno sguardo, grazie.


 stesso ad errori di tipo random.
Già, ora che mi ci fai pensare, questa è una cosa del tutto diversa. E'
equivalente alla chiamata MEMORY( -1 ) che, in Clipper, forza, appunto,
il garbage collector ad agire. Evidentemente anche in VO, quando si è
all'interno di un loop, l'attività del GC è bloccata.


 hanno metodi tipizzati e il compiler pragma:
Io direi che Classmate ha pochissimo in comune con
le GUI di VO.
Ciao
Paolo Cherubini

 EMG


 nRisultato := REAL8(_CAST, PCALL( pfunc, param1, "pippo" ) )
Sei sicuro che sia necessario il casting ?
Ero convinto che per richiamare una DLL  scritta in VO e utilizzata in
programmi VO e linkata  dinamicamente non servisse.
Ciao,
       Fabrizio Malaguti


programmi VO e linkata  dinamicamente non servisse.
Il _CAST serve per il valore di ritorno, perchč PCALL ne restituisce
il puntatore.
Gli argomenti invece vengono passati cosě come sono.
Ciao


 variabile cS, significa che pszS contiene un puntatore non piu' valido.
Continuo ad essere perplesso: se veramente potesse succedere questo
allora cosa ne è di una variabile passata per riferimento? Forse non
esiste in VO il passaggio per riferimento (come l'operatore @ in
Clipper)? Se esiste, allora l'indirizzo passato perderebbe di validità
dopo che fosse entrato in azione il GC. E siccome tale indirizzo
potrebbe essere stato propagato a chissà quante funzioni direttamente
(passandolo per parametro) oppure attraverso codeblocks (cosa molto più
ardua da districare), la sistemazione di tutto questo casino da parte
del sistema di runtime la vedo alquanto difficoltosa (tendente
all'impossibile, direi).
EMG
--


 EMG


 Gli argomenti invece vengono passati cosě come sono.
Ok. Grazie della spiegazione.
Ciao,
       Fabrizio Malaguti


Ok. Grazie della spiegazione.
figurati :-)
