Autore Topic: Come importare e/o usare la funzione "memcopy" di Linux ?  (Letto 1372 volte)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Come importare e/o usare la funzione "memcopy" di Linux ?
« il: 25 Gennaio 2014, 16:45:43 »
Riporto questa discussione apparsa nella M.L. ufficiale:


" G'day all:
Linux has "memcopy" and Windows has "MoveMemory".  How do I import or
reference memcopy into Gambas?  I can see that I should be able to
effect this function using stream Memory Read and Write, but it may
not work as fast?  I need to use this many times
Carl.
"


" Why do you need to copy memory? You should not, it's dangerous.

--
Benoît Minisini
"


" If you have problems to declare memcpy on Gambas, you will very probably
have much more problems with it (unexpected behavior, random crashes, etc).
There very probably is alternative method for this. As Benoit already ask,
why you need it?

Anyway:
Private Extern memcpy(dest As Pointer, src As Pointer, count As Integer) As
Pointer In "libc:6"

Jussi
"


" Good evening Benoit:
Actually, it is the C function memmove that I
want to use.  I will be using it all the time to
shuffle array elements along, like a shift
register in data filtering.  The Windows function
CopyMemory  is very fast and much more efficient
than using do loops in VB6.  It is also very
useful in handling serial input byte data which
comes in varying size packets.  I have been using
the Win kernel CopyMemory for years in VB6
without problems and I wish to implement similar
functionality in the port to Gambas.  This
evening I have got as far as being able to run
memmove in Gambas, but not yet correctly.  I'm
still struggling a bit with pointers.  It seems I
cannot use VarPtr on a (1-D) integer array at a
particular element number of a linear, say,
integer array like VarPtr(iArray[18]).  So I have
got as far as trying iPtr = VarPtr(iArray) +  72
(for that example) without success.  I have
assumed my iPtr (declared as a Pointer) is an
integer value that increases by 4 for each
integer element, but I could be off the
track.  Being "dangerous" does not unduly concern
me - my computer won't blow up! I just need to
move blocks of data back and forth quickly!
Carl
"


" If you just need to move a number of consecutive elements from one array
to another array of the same type, I can add a method for that.

Something like: AnArray.CopyTo(AnotherArray, DestinationIndex,
SourceIndex, Count)

That method will spend a little time to check its arguments so that you
don't crash everything.

It will be far more reliable than trying to deal with pointers when you
don't know how exactly things are implemented. Moreover, once you got
it, your code may break in the future as soon as the internal
implementation changes.

--
Benoît Minisini
"


" iArray.Data gives the pointer you need.

> Moreover, once you got it, your code may break in the future as soon as
> the internal
> implementation changes.
>

What you mean by this? I'm expecting normal Gambas arrays to be read in
external libraries as c array when passed as iArray.Data. So far this has
worked perfectly. And in my understanding embedded arrays are useful only
if they are part of structure that should be passed to some library.
Changing this would break a lot of things. Have I understood something
incorrectly?

Jussi

Jussi
"
« Ultima modifica: 25 Gennaio 2014, 16:49:15 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Come importare e/o usare la funzione "memcopy" di Linux ?
« Risposta #1 il: 26 Gennaio 2014, 04:05:24 »
...continua...


" Benoit:
That would indeed be most helpful. A point about my particular uses.
The nice thing about the CopyMemory function in
Windows and the memmove in Linux (as I undersand
it) is that you can copy a simple array to itself
with the indices shifted - left or right.  For
example, treating the array as a "stack", I can
continually update the array by shifting all the
values one place to the left, thus discarding the
first and adding a new value to the last (highest
indice).  That way I can keep a current "last 20
values" say, and also keep a current sum (for an
adequate time) by just subtracting the old first
value and adding the new last one.  That's one
use.  Just how these functions implement that I
am unsure, but the effect is a pseudo copy to
some intermediate array and then a second copy
back to the original.   This pseudo array is transparent to the user.
Another use is to make space in front of an array
in which to add an older array segment.  I use
this in dealing with "remainders" from previous
serial port inputs.  I don't always know what to
expect in the input stream, so I may have some
leftovers I wish to add to the start of a
subsequent input.  The resize method allows me to
make room, then shift the later segment to the
right of the input array to make room for the earlier in front.


Jussi:
Thanks, I had missed that property.  Function memmove now works as I
think it should.  The pointer acts like an integer giving the
starting location of the array in bytes.  As I recall, in VB6 I can
use "iArray" as a variable and it is assumed to mean
"iArray(0)",  Or, I could have specified the element "iArray(0)" as
an argument in a function expecting a simple variable.  Not so in
Gambas.  (I'm not being critical, these are things I am finding out
about Gambas).  In the literature I have perused, there is not too
much about arrays (a little in Rittinghouse ABGTG) and even less
about passing arguments to procedures.  To my gratification,
Rittinghouse says (Vol. 1 p.53) clearly that 1-D arrays are objects
and elsewhere I read that objects can be passed as arguments, both of
which statements were supported when my test showed I could pass  a
1-D array as an argument to a procedure in another class
(form).  That's something I  could not do in VB6, without resorting
to User-Defined-Types (UDT).  I live and learn!

Carl
"
« Ultima modifica: 26 Gennaio 2014, 14:52:57 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Come importare e/o usare la funzione "memcopy" di Linux ?
« Risposta #2 il: 26 Gennaio 2014, 17:45:35 »
...continua...


" >in VB6 I can
> use "iArray" as a variable and it is assumed to mean
> "iArray(0)",  Or, I could have specified the element "iArray(0)" as
> an argument in a function expecting a simple variable.


The difference is that in Gambas arrays are objects.


> I read that objects can be passed as arguments

True, but not to library written in C which doesn't support objects at all.
And with other languages, I don't think the object structure in memory is
same (=compatible). However you can pass objects as arguments in libraries
written with Gambas.


Jussi
"


----

Ad ogni modo io propongo una cosa così:
Codice: gambas [Seleziona]
' void *memcpy(void *str1, const void *str2, size_t n)
Private Extern memcpy(str1 As Pointer, str2 As Pointer, n As Integer) In "libc:6"



Public Sub Main()

  Dim src, dest As Pointer
  Dim s As String = "Questa è una prova con la funzione 'memcpy()'."
 

    src = Alloc(s)
    dest = Alloc(Len(s))
   
    memcpy(dest, src, Len(s))
   
    Print "Dopo memcpy, " & Quote("dest") & ":\n"; String@(dest)

    Free(src)
    Free(dest)

End
« Ultima modifica: 11 Marzo 2014, 02:38:34 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
« Ultima modifica: 18 Marzo 2016, 19:17:34 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re:Come importare e/o usare la funzione "memcopy" di Linux ?
« Risposta #4 il: 19 Marzo 2016, 02:10:22 »
Per me ha ragione Minisini, bisogna stare attenti ad usare queste cose. E' un attimo scrivere dove non si deve e fare qualche disastro.
Se c'e' bisogno di copiare un array dentro un altro preferisco usare quei pochi secondi in più ma essere sicuro che tutto vda bene.
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come importare e/o usare la funzione "memcopy" di Linux ?
« Risposta #5 il: 19 Marzo 2016, 22:38:13 »
...bisogna stare attenti ad usare queste cose. ...
A mio avviso, volendo utilizzare la funzione "esterna" di C 'memcpy()' in Gambas, mediante Extern, se i due Puntatori, da passare a detta funzione esterna (come 1° e 2° argomento), vengono creati con la funzione di Gambas " Alloc() " il rischio di eventuale sovrapposizione è evitato.
La funzione Alloc(), che molto probabilmente utilizza la funzione di C " malloc() ", assegna alla variabile di tipo  Puntatore, da essa ritornato, un'area di memoria "riservata" e quindi "sicura".
Se gambas si permettesse di andare a pasticciare con le aree di memoria che il programmatore ha chiesto indirettamente (ossia attraverso Alloc() di Gambas ! ) alla funzione di C malloc() di allocare, di riservare, ci sarebbe un casino. Ma se Gambas avesse, in ipotesi, un suo meccanismo interno, indipendente dalla funzione di C  malloc(), per darti delle aree di memoria, sarebbe folle a non dartele distinte come fa la funzione di C malloc().
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come importare e/o usare la funzione "memcopy" di Linux ?
« Risposta #6 il: 12 Marzo 2018, 04:07:25 »
Un esempio fra molti, mescolando risorse native di Gambas e funzioni esterne, potrebbe essere la copia di dati da un vettore di tipo Byte[ ] a un altro vettore di tipo Byte[ ]:

Codice: [Seleziona]
Library "libc:6"

' void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)
' Copy N bytes of SRC to DEST.
Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long)


Public Sub Main()

  Dim sor As Byte[]
  Dim des As Byte[]
  Dim b As Byte
 
   sor = [11, 22, 33, 44, 55, 66, 77, 88]
   
   des = New Byte[sor.Count]
 
' Copia un numero "sor.Count" di dati dall'area di memoria di "sor" nell'area di memoria di "des":'
   memcpy(des.Data, sor.Data, sor.Count)
   
' Verifica il risultato:'
   For Each b In des
     Print b
   Next

End
« Ultima modifica: 12 Marzo 2018, 11:07:02 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come importare e/o usare la funzione "memcopy" di Linux ?
« Risposta #7 il: 13 Marzo 2018, 02:55:03 »
Di seguito un esempio simile al precedente, ma reso più complesso, poiché i dati andranno scritti nell'apposito membro (void *data) della Struttura, chiamata CARRAY e contenuta nel file sorgente ".../main/gbx/gbx_c_array.h" dell'Interprete.

Codice: [Seleziona]
Private Const NUM As Integer = 8


Library "libc:6"

' void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)
' Copy N bytes of SRC to DEST.
Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long)


Public Sub Main()

  Dim p As Pointer
  Dim sor, des As Byte[]
  Dim b As Byte
 
   sor = New Byte[]
   sor = [11, 22, 33, 44, 55, 66, 77, 88]
   
   des = New Byte[NUM]

' Penetra nella Struttura denominata CARRAY, contenuta nel file sorgente ".../main/gbx/gbx_c_array.h":'
   p = Object.Address(des)

' Copia una quantità "NUM" di dati dall'area di memoria di "sor" nell'area di memoria di "des":'
   memcpy(Pointer@(p + 32), sor.Data, NUM)
   
' Verifica il risultato:'
   For Each b In des
     Print b
   Next
 
End
Vedi anche:
http://www.gambas-it.org/wiki/index.php?title=Configurazione,_organizzazione_ed_impostazione_dell%27array_secondo_i_sorgenti_di_Gambas

« Ultima modifica: 13 Marzo 2018, 02:57:23 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come importare e/o usare la funzione "memcopy" di Linux ?
« Risposta #8 il: 14 Marzo 2018, 03:28:29 »
Aggiungo quest'altro caso molto più complesso.

...ricordate queste mie parole ?
CHI DOMINA la MEMORIA, DOMINA il MONDO degli "OGGETTI"

Ogni "Oggetto" di Gambas è innanzitutto costituito da più porzioni di memoria, organizzate secondo le specifiche Strutture previste dai sorgenti di Gambas per ciascun Oggetto, dedicate a immagazzinare i dati che caratterizzeranno gli Oggetti medesimi.

Poter e sapere dunque accedere alle aree di memoria di un Oggetto, significa poter modificare i valori delle sue proprietà.

Con un'operazione di ingegneria si possono modificare "geneticamente" Oggetti che in apparenza sono quelli originari, e invece fanno riferimento ad altri Oggetti.
Ponete sul Form una "PictureBox" e un "TextBox".
Codice: [Seleziona]
Library "libc:6"

' void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n)
' Copy N bytes of SRC to DEST.
Private Extern memcpy(__dest As Pointer, __src As Pointer, __n As Long)


Public Sub Form_Open()

  Dim p1, p2 As Pointer
  Dim t1, t2 As Pointer
  Dim s As String
 
  With PictureBox1
    .Background = Color.Yellow
    .Foreground = Color.Blue
  End With

' Accediamo profondamente nelle Strutture sorgenti della "PictureBox":'
  p1 = Object.Address(PictureBox1)
  p2 = Pointer@(p1)
 
' Accediamo profondamente nelle Strutture sorgenti del "TexteBox":'
  t1 = Object.Address(TextBox1)
  t2 = Pointer@(t1)
 
' Facciamo in modo che la "PictureBox" punti alle risorse della "TextBox" !!!'
   memcpy(p1, t1, 144)
   memcpy(p2, t2, 512)
   
' ...è la PictureBox a spostarsi ?'
   PictureBox1.X = 500

' Scusate...ma...quando mai la PictureBox ha avuto la Proprietà ".Text" ?!?!?'
   PictureBox1.Text = PictureBox1.Name

' Eeeh ! ...che nome ha la "PictureBox" ???????'
   Print PictureBox1.Text, TextBox1.Text
   
' Scoprirete che le risorse della PictureBox non sono più quelle della Classe PictureBox, bensì della TextBox !!!'
   For Each s In Object.Class(PictureBox1).Symbols
     Print s
   Next

End



Public Sub TextBox1_Enter()  ' Provate a passare con il mouse sulla "PictureBox".... '
 
  Print "Passaggio del Mouse sul TextBox1 ?"
 
End


Chiameremo questo caso: Oggetti Geneticamente Modificati   ;D
« Ultima modifica: 14 Marzo 2018, 03:32:05 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »