| Renzo Di Lorenzo |
CopyMemory
Salve,
Sto realizzando un progetto che utilizza una dll YAZ pilotata da una interfaccia ZOOM (http://zoom.z3950.org). Vorrei migrare il codice in NET. Il punto è che la ZOOM utilizza molte chiamate alla API di base YAZ la quale restituisce un puntatore long ai dati veri e propri. Non ho dimestichezza con queste cose, ho notato che il punto principale è questa API CopyMemory o lstrcpy, che pare che trasformi il puntatore in dati fruibili. Come mi devo comportare in NET? Posto un piccolo esempio di codice VB6, se qualcuno gentilmente mi puo' erudire sull'argomento, glie ne sarei molto grato (caffè e brioscina pagato)... Private Declare Function lstrlen Lib "KERNEL32" Alias "lstrlenA" (ByVal ptr As Long) As Long Private Declare Function lstrcpy Lib "KERNEL32" Alias "lstrcpyA" (ByVal dest As String, ByVal ptr As Long) As Long Private Declare Function lstrcpyn Lib "KERNEL32" Alias "lstrcpynA" (ByVal dest As String, ByVal ptr As Long, ByVal size As Long) As Long Public Declare Sub RtlMoveMemory Lib "KERNEL32" (ByRef dest As Any, ByRef ptr As Any, ByVal size As Long) Private Declare Sub StrCpy Lib "KERNEL32" Alias "RtlMoveMemory" (ByVal dest As String, ByVal ptr As Long, ByVal size As Long) Public Function CopyString(ptr As Long, s As Long) As String Dim l As Long Dim ret As String If ptr = 0 Then ret = "" Else If s = -1 Then l = lstrlen(ptr) ret = String(l, vbNullChar) l = lstrcpy(ret, ptr) Else ret = String(s, vbNullChar) StrCpy ret, ptr, s End If End If CopyString = ret End Function ...non so dove mettere le mani :-((((... Grazie a Tutti e Buon Lavoro.. Rei. |
| WIlliam Franchini |
Re: CopyMemory
Ciao
se non ho capito male la tua funzione VB riceve in input un puntatore ad una stringa e la lunghezza dei dati e restitusice una stringa VB. In .NET puoi evitare di chiamare direttamente le API di Windows (anche se potresti) e realizzare la stessa cosa tramite una chiamata ad un metodo della classe Marshal come: System.Runtime.InteropServices.Marshal.PtrToStringAnsi(IntPtr, int) che fa proprio questo trasformando un puntatore ad una stringa ANSI (ci sono anche altre versioni) in una stringa .NET ciao William |
| Renzo Di Lorenzo |
Re: CopyMemory
Dunque William, Spero che tu sia online,..
Sto provando a convertire quella classe da vb6 a net. Ho provato a sostituire il codice : 'Calcola la dimensione del Risultato.. Dim GetSize As Long = ZOOM_resultset_size(hZOOM_resultset) Dove getSize è un long : ti mando anche il valore.. :1125899906842624 Ora, ho provato a utilizzare il tuo esempio di dichiarazione che accetta un System.IntPtr come parametro ma...... MsgBox(System.Runtime.InteropServices.Marshal.PtrToStringAnsi(DirectCast(GetSize, System.IntPtr))) ...sul GetSize mi dà errore e dice : "L'operando "DirectCast" deve avere un tipo di riferimento, ma "Long" è un tipo di valore." Non capisco, il valore di ritorno di GetSize è o non è un puntatore ad una stringa?.. Dovrebbe ritornare un valore che indica il numero di record richiesti (nel caso specifico ovvio).. ma non capisco come posso convertire un long in un System.IntPtr. Can You Help Me?...... |
| WIlliam Franchini |
Re: CopyMemory
Posto che GetSize sia un valore che può essere utilizzato come puntatore devi costruire un IntPtr con quel valore:
IntPtr ptr = new IntrPtr(GetSize); ciao William |
| Renzo Di Lorenzo |
Re: CopyMemory
Si, dunque, c'èra un problema di fondo,le dichiarazioni API originali avevano ancora la dichiarazione del valore di ritorno a LONG. ho sostituito con system.Int32 e si comincia a vedere qualcosa.
Nello specifico ho un metodo che ritorna dati raw (???) ti faccio vedere cosa ho fatto : rtnVal = ZOOM_record_get(hzr, "raw", rtnLen) Dim ptr As New System.IntPtr(rtnVal) Dim rawdata As String = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptr) MsgBox(rawdata) Questi alcuni valori stringa di rawdata : rawdata "°ow" String rawdata "à—¢" String rawdata " ¸¢" String Cosa Sono?... (Grazie Infinite William...) |
| Renzo Di Lorenzo |
Re: CopyMemory
Si funziona, il valore lo ritorna correttamente.
|
| WIlliam Franchini |
Re: CopyMemory
on 29. Oct 2002 15:56 Renzo Di Lorenzo wrote:
> Si funziona, il valore lo ritorna correttamente. Quindi tutto ok ? ciao William |
| Renzo Di Lorenzo |
Re: CopyMemory
Hai letto il post precedente? Quella funzione mi ritorna un valore incomprensibile. Io credo si tratti di un ulteriore puntatore all'effettivo record. Quindi non dovrei convertirlo in stringa. Probabilmente dovrei usare quel puntatore per riempire una struttura che contiene il record vero e proprio. Purtroppo non c'è supporto per queste librerie proprietarie. Lo Zoom è stato costruito da un certo Mr. Tom Habing, il quale ha realizzato l'interfaccia di comunicazione verso questa dll YAZ che effettivamente instaura il collegamento con i server tramite il protocollo Z39.50. Argomento complicato. Comunque sia, sto migrando piano piano il codice cercando qua e là informazioni su internet. Una api che non riesco a traslare è la RTNMoveMemory (Kernel32), non so se il nome è esatto (non ho con me il sorgente ora, ma oggi pomeriggio si), e comunque viene utilizzata molto in questo Zoom. Cosa ho fatto : ho migrato tutto il codice sostituendo le chiamate API CopyString con quella che mi hai indicato e funziona perfettamente. Credo che con la migrazione di quest'altra API dovrei risolvere.. ma non so sostituirla.. Puoi darmi un aiutino? Grazie Infinite.
Rei. |
| WIlliam Franchini |
Re: CopyMemory
on 30. Oct 2002 11:33 Renzo Di Lorenzo wrote:
>Una api che non riesco a traslare è la RTNMoveMemory (Kernel32), non so se > il nome è esatto (non ho con me il sorgente ora, ma oggi pomeriggio si), e comunque viene utilizzata molto in > questo Zoom. Cosa ho fatto : ho migrato tutto il codice sostituendo le chiamate API CopyString con quella che > mi hai indicato e funziona perfettamente. Credo che con la migrazione di quest'altra API dovrei risolvere.. ma non so sostituirla.. Puoi darmi un aiutino? Sei sicuro non si tratti di RTLCopyMemory ? In questo caso è una funzione che si trova in kernel32.dll (o in WinNt.dll) e che copia un'area di memoria in un'altra. Non dovresti avere problemi a chiamarla tramite P/Invoke. Non ho testato, ma credo sia una cosa del genere in VB.NET <DllImport("kernel32.dll", EntryPoint:="RTLCopyMemory")> _ Public Shared Sub CopyMemory(ByVal Destination As IntPtr, ByVal Source As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal Length As Integer) End Sub Se vuoi mappare un puntatore su una struttura puoi usare un altro metodo di Marshal: PtrToStructure() ciao William |
| Renzo Di Lorenzo |
Re: CopyMemory
Si la API è quella, infatti non ricordavo il nome esatto. Oggi pomeriggio continuero' a lavorare su questo progetto. Provero' a utilizzare quella che mi hai indicato tu. Purtroppo come ti dicevo, la difficoltà maggiore è il "senso" di questi maledettissimi records che tiro giu'.. Ma qui ci vuole un guru dell'argomento. Nel frattempo ti ringrazio moltissimo per la collaborazione, ho imparato molte cose nuove, e quando succede sono molto contento:-)
Fino a che ora sei online nel pomeriggio? Grazie Infinite. REi. |
| WIlliam Franchini |
Re: CopyMemory
Ma qui ci vuole un guru dell'argomento. Nel frattempo ti ringrazio
> moltissimo per la collaborazione, ho imparato molte cose nuove, e quando succede sono molto contento:-) > Fino a che ora sei online nel pomeriggio? > Grazie Infinite. > REi. non so. ti lascio l'email privata per non "intasare" il forum: wfranchini@acm.org prego William |