Logo UGIdotNET

Discussione 'CopyMemory'

# Pubblicato il 22 ott 2002 14.54 - Rispondi
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.
# Pubblicato il 25 ott 2002 15.05 - Rispondi
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
# Pubblicato il 29 ott 2002 14.29 - Rispondi
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?......
# Pubblicato il 29 ott 2002 14.42 - Rispondi
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
# Pubblicato il 29 ott 2002 15.55 - Rispondi
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...)
# Pubblicato il 29 ott 2002 15.56 - Rispondi
Renzo Di Lorenzo
Re: CopyMemory
Si funziona, il valore lo ritorna correttamente.
# Pubblicato il 30 ott 2002 10.59 - Rispondi
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
# Pubblicato il 30 ott 2002 11.33 - Rispondi
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.
# Pubblicato il 30 ott 2002 12.06 - Rispondi
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
# Pubblicato il 30 ott 2002 12.09 - Rispondi
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.
# Pubblicato il 30 ott 2002 13.04 - Rispondi
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

© 2001 User Group Italiano UGIdotNET. Tutti i diritti riservati. Note legali. - Partita IVA 01927050185