Usare le dll

Posso accedere alle dll in windows ?
Nella documentazione Xojo ho visto solo l’ uso del file user32.lib e mi sembra di capire che user32.lib l’ API per gestire la libreria Win32.dll.
E’ corretto ?

Non ho mai usato le dll di windows, so che si possono usare.
Cosa devi fare esattamente ?

Ho un Pc non collegato alla rete che fa un Log dei dati ricevuti via seriale.
Per avere l’ orario sempre sincronizzato ho collegato un’ antenna GPS (sempre via seriale).
Vorrei ora di sincronizzare il PC con il GPS.
Ho provato con i comandi Shell via Xojo ma non mi lascia (pure con il comando “runas” entrando come amministratore), mentre se immetto i comandi da tastiera funziona.
In internet ho trovato esempi dove usano le dll di sistema ma con Xojo non so se le posso utilizzarle.

Sacha,

Post the code that doesn’t work in the shell and what error you get, maybe someone can help you with that. Also, post the example you found of using a dll, and we can try to convert it to Xojo.

Sorry I can’t reply in italian.

Julen

Certo che le puoi utilizzare. Guarda gli esempi relativi alle declare

Trovato !!!

Di seguito le righe di programmazione:

[code]'Creazione del blocco di memoria
Dim TimeMemoryBlock as new MemoryBlock(16)
Dim result as boolean
'Organizzazione del blocco di memoria 2 bytes (Uword = Uint16)
'0 - 1 = Anno
'2 - 3 = Mese
'4 - 5 = Giorno della settimana
'6 - 7 = Giorno del mese
'8 - 9 = Ora
'10 - 11 = Minuti
'12 - 13 = Secondi
'14 - 15 = Millisecondi

'Settaggio anno
TimeMemoryBlock.UInt16Value(0) = 2018
'Settaggio mese
TimeMemoryBlock.UInt16Value(2) = 9
'Settaggio giorno della settimana
TimeMemoryBlock.UInt16Value(4) = 5 'venerdi
'Settaggio giorno del mese
TimeMemoryBlock.UInt16Value(6) = 22
'Settaggio ora
TimeMemoryBlock.UInt16Value(8) = 20
'Settaggio minuti
TimeMemoryBlock.UInt16Value(10) = 33
'Settaggio secondi
TimeMemoryBlock.UInt16Value(12) = 2
'Settaggio millisecondi
TimeMemoryBlock.UInt16Value(14) = 0

Declare Function SetSystemTime Lib “kernel32” (TimeBlock as ptr) as boolean

result = SetSystemTime(TimeMemoryBlock)
TextField1.text = str(result)[/code]

Il programma per funzionare deve essere compilato ed eseguito come amministratore, in caso contrario la funzione dar sempre false.

Domanda:
Per interagire con le dll devo utilizzare sempre i blocchi di memoria o solo se le funzioni contengono dati strutturati ?

Dipende dalla funzione esposta dalla dll

Sto cercando di capire come manipolare le dll ma la cosa si fa complicata.

Ad esempio, nel forum in inglese di Xojo trovo come ricavare il nome dell’ utente.

[code]Declare Sub GetUserNameW Lib “AdvApi32” ( name As Ptr, ByRef size As Integer )

Dim mb As New MemoryBlock(1024 )
Dim size As Integer = mb.Size

If System.IsFunctionAvailable( "GetUserNameW", "AdvApi32" ) Then
  GetUserNameW( mb, size )
  current_user=mb.WString( 0 )
Else

…[/code]

Perch i valori che devo leggere dalla funzione GetUserNameW si trovano tra le parentesi come se fossero dei parametri da passare alla funzione ?

Mi aspettavo ad esempio: GetUserNameW() as string.

Perch dichiari un metodo che richiamer la funzionalit della DLL e questa richiede (nel caso specifico, guardando i parametri) una area di memoria e la sua dimensione (che poi andr a modificare, visto che by ref)
Chiamata la funzione di sistema il tuo memory block contiene il valore richiesto che puoi ottenere leggendone la wString.

In pratica la maggior parte delle DLL ha i propri tipi o strutture di dati che quindi vanno convertiti o letti in qualche modo per ottenere l’informazioni che ti serve in Xojo.

GetUserNameW

Da quanto ho capito i blocchi di memoria tra DLL e applicazioni sono sempre condivisi, ovvero: indico alla funzione che pu leggere o scrivere i dati dove il mio programma ha “riservato” il blocco di memoria o pi precisamente dove inizia l’ occupazione del blocco.
E’ corretto ?

Dipende dalla funzione chiamata.
Generalmente molte funzioni di Windows richiedono un’area di memoria allocata dal programma dove il sistema “depone” i dati richiesti o riceve i parametri necessari alla funzione.
In ogni caso e’ sempre necessario fare riferimento alla documentazione della dll.
Per quanto riguarda Windows il sito docs.microsoft.com riporta tutta la documentazione necessaria.

Ricorda che in Xojo le structure sono pensate principalmente per l’interfaccia appunto con le dll.
Ad esempio nel tuo caso dove hai utilizzato la funzione SetSystemTime avresti potuto dichiarare una structure analoga alla SYSTEMTIME al posto di un MemoryBlock e utilizzarla come paramtro con il prefisso ByRef che appunto passa il parametro tramite indirizzo (puntatore).

Ora prover la chiamata a SetSystemTime con structure e condividendo la variabile con byref.

Grazie per le preziose informazioni

Ho creato la struttura “TimeSetStructure”, poi ho creato l’ oggetto TimeToSet e l’ ho popolato con i parametri.

Dim TimeToSet as TimeSetStructure TimeToSet.Anno = 2018 TimeToSet.Mese = 9 TimeToSet.GSett = 2 TimeToSet.GMese = 25 TimeToSet.Ora = 14 TimeToSet.Minuti = 0 TimeToSet.Secondi = 0 TimeToSet.millisecondi = 0

Fin qui tutto bene.

Ora vorrei inserire questi dati nella funzione della DLL ma non so come.

Ho provato a cercare qualche funzione che mi dia il puntatore della variabile TimeToSet ma non la trovo.

Come posso fare ?

intanto devi istanziare la variabile con la struttura come nuova variabile :
Dim TimeToSet as New TimeSetStructure
Altrimenti mi sa ti da errore…

Un a struttura non un oggetto un tipo per cui non devi usare new

Il problema che non riesco a risolvere come passare i dati della struttura “TimeToSet” alla funzione che mi richiede una variabile PTR.
Non ho la pi pallida idea di come fare.

[code]Declare Function SetSystemTime Lib “Kernel32.dll” (ByRef lpSystemTime As SYSTEMTIME) As Int32

Dim TimeToSet As SYSTEMTIME
TimeToSet.Year = 2018
TimeToSet.Month = 9
TimeToSet.DayOfWeek = 2
TimeToSet.Day = 25
TimeToSet.Hour = 14
TimeToSet.Minute = 0
TimeToSet.Second = 0
TimeToSet.Milliseconds = 0

Dim ok As Int32
ok = SetSystemTime(TimeToSet)
If ok = 0 Then
'ERROR
End If[/code]

Structure SYSTEMTIME Year As UInt16 Month As UInt16 DayOfWeek As UInt16 Day As UInt16 Hour As UInt16 Minute As UInt16 Second As UInt16 Milliseconds As UInt16 End Structure

https://blog./2017/01/22/windows-to-xojo-data-type-conversion/

L’esempio di Julian funziona. (Grazie)

Ho notato per che stato dichiarato il valore che la funzione restituisce come int32 e non boolean.

Testando la funzione con entrambi i tipi di dati non ho alcun errore.

Perch ?

Google translate, mi dispiace :slight_smile:

You can use either in this case, sometimes you need the returned value, sometimes you don’t so I always use the correct type.

Puoi usare entrambi in questo caso, a volte hai bisogno del valore restituito, a volte non lo fai, quindi uso sempre il tipo corretto.

BOOL WINAPI SetSystemTime( _In_ const SYSTEMTIME *lpSystemTime );

typedef int BOOL;
INT A 32-bit signed integer. The range is -2147483648 through 2147483647 decimal.

https://blog./2017/01/22/xojo-data-types/

Int32	-2,147,483,648 to 2,147,483,647

If you want a boolean you can do it like this, or you can change the declare if you don’t want the Int32 answer

Se vuoi un booleano puoi farlo in questo modo, oppure puoi cambiare il DECLARE se non vuoi la risposta Int32

Dim bOK As Boolean bOK = CType(ok, Boolean)