"Hi.

It would be nice to see simple code (not in video) how to create memory and
read/write data to it."

If you get the Project it comes with an example how to use in the class
side of the CPPBridge Class and its in methods retrieveSharedValueStep1 and
retrieveSharedValueStep2, first one open the files , access the shared
memory and pick the value from shared memory, the second unmaps the file
from memory and closes the file (access to shared memory remains , the file
is is just no longer auto-saved by the OS). All methods are documented and
class comes with a comment.

Yes basically what I have done is to extend the LibC class because every
function I am using is from LibC aka as C standard library that comes
included in MacOS and Linux. Windows is doing its own thing , I have not
ported to windows yet, though if you have something that install LibC (part
of GCC) on Windows probably  it works there too. But I will make a native
port to Windows as well because its crucial for my gamers to play my games
out of the box with no additional install of libraries or what else.

One thing I did not make clear, the file opened plays a minor role for the
shared memory its just used to store a dumb of the memory just like we do
with the Pharo image (though in the case of Pharo image is bytecode) . As
such file I/O is never involved in accessing the data instead it gives
direct access to the memory , hence why its blazing fast.

I don't have any issue to add this to LibC of UFFI but this decision is to
Esteban, I just did not want to put more things in the Pharo image that
people wont use since we try to decrease the size of the image.

CPPBridge currently does not provide anything else, however in truth it
does not need to. The moment you share date, that means you share state and
you can even control code execution. Unfortunately C/C++ is not a dynamic
language like Python, with Python all I had to do was to pass strings to
python eval() and let python execute whatever command I wanted, but with
C++ these things will have to be precompiled in order to work.

Most likely I will be adding in the near future classes and method of
convenience for using C++ libraries/code from Pharo and Pharo
libraries/code from C++. Possible will add also Python support. Other
language that can be supported are C# (and any other language running on
.NET or Mono related) , Java (again any other language running on JavaVM ),
Ruby , Pearl, D, J, Julia, R , so pretty much any language out there. C/C++
obviously is optional.

I am pasting bellow the source of the two methods I mentioned, code can be
also viewed here

https://github.com/kilon/CPPBridge/blob/master/CPPBridge.package/CPPBridge.class/class/retrieveSharedValueStep1.st

and here

https://github.com/kilon/CPPBridge/blob/master/CPPBridge.package/CPPBridge.class/class/retrieveSharedValueStep2.st

---------------------------------------------------------
 retrieveSharedValueStep1
<example>
"This method is an example that retrieves a struct from a shared memory
section, in order for this example to work you need you first copy paste
the contents of the Example Souce Code of the C++ file in the comment
section of this class to a C++ source code file and compile it a run then
replace the path of in this code of CPPBridge openFile: with the correct
path of the bin that the C++ files has created , in order for this to work
also you need to execute the C++ example first so it creates and file and
share the memory.

After executing this method you can execute retrieveSharedValueStep2 to
unmap and close the memory mapped file (keeps sharing the memory it just
does not store it to the file)"

| instance fdNumber lseek mmapPointer data struct |

instance := CPPBridge new.
fdNumber := CPPBridge openFile: '/Users/kilon/git/Pharo/Atlas/mmapped.bin'
flags: (O_RDWR) .

"Warning !!! You must change the path to the file that is located in your
hard drive. The file should be at the same location you built
atlas-server.cpp which is responsible for creating the file."

lseek := CPPBridge lSeek_fd: fdNumber range:3999  value:0.
mmapPointer := CPPBridge  mmap_adress: 0 fileSize:4000  flag1: (PROT_READ |
PROT_WRITE )flag2: MAP_SHARED  fd: fdNumber  offset: 0  .
struct := CPPStruct pointTo: (mmapPointer getHandle ).


data :={ instance.  fdNumber . lseek. mmapPointer  .  struct}.
data inspect.

ExampleDATA := data.
^data

"
This is an alternative array that contains only the two values of the C
Struct :

1) data = char[3000]  this is where we store the string
2) count = int this is where we store the size of the string

struct := {(mmapPointer getHandle  copyFrom: 1 to:3000 )asString .
(mmapPointer getHandle integerAt: 3001 size:4 signed: false)}.

mmapPointer is the pointer that points to the first byte of the shared
memory.

getHandle gives us the memory adress that the pointer points to

copyFrom:1 to:3000 copies byte from byte 0 (remember C counts from 0 ,
Pharo counts from 1) to byte 3000 because the string we store is stored as
a char array of 3000 elements, each element is a char, each char is 1 byte
in leght and represents a single character of the string.

on the other hand integerAt: 3001 size: 4 signed: false returns us the
value count memeber of the C struct . its an integer in position 3001
because our string is a char[3000] and the size is 4 bytes because its an C
int, signed false because we use no negative values because it does not
make sense for a string to have negative length."

------------------------------------------

retrieveSharedValueStep2
<example>
"this one is to be triggered after retrieveSharedValueStep1 when we are
finished with the shared memory and we want to erase it and close the
memory mapped file

ExampleDATA = { CPPBridgeinstance . fd . lseek . mmap . struct}"

CPPBridge munmap_data: (ExampleDATA at: 4) filesize: 4000.
CPPBridge  closeFile: (ExampleDATA at: 2).

Reply via email to