[REBOL] Re: How to send big string to library and back?
From: jeff:rebol at: 16-Apr-2001 7:44
Howdy, Petr:
> But my friend asked me a question I am not able to answer
> him. According to him, in C language, string is ended by
> "0" char. So if my image data will contain "0" char, it
> could be regarded as an end of a tring by internal Rebol
> library interface routines.
First, let me clarify the terminology:
In REBOL: In shared library:
------------------------------------------
routine! "external library routine"
In REBOL you may have string data that contains null
characters. REBOL doesn't care. In C, operations that work
on a string consider the null character as a terminator.
If you are working with an external library routine that
expects image data, then that routine most likely does not
consider null characters as the end of data.
So you can happily pass along string! to any external
library routine that is expecting a pointer to any kind of
data.
The only hitch is having that memory come back. The way
COMMAND works now is that if you have a return type of
string! (or char*) then REBOL/Command must find the null
terminator-- otherwise you have some unbounded string
hanging out (which can't happen).
If you have a data buffer going off to a shared library from
command that you would like to operate on both in REBOL and
in the external routine, I recommend: 1. doing all your
manipulations on that data from REBOL first. 2. returning an
integer! instead of a string! which allows you to hold the
pointer to that memory but does not provide it. 3. Pass a
reference (address of) to your buffer to an external routine
which will modify it "in place".
For example:
// FOR UNIX --
REBOL [
Needs: [Command]
]
write %zap-buff.c reform ["#include <string.h>" newline
"void zap_buff(char ** buf, char what, int len) {memset(*buf, what, len);}"
]
call/wait "gcc -fPIC -shared zap-buff.c -o zap-buff.so"
zbl: load/library %zap-buff.so
zap-buff: make routine! [
b-wrap [struct! [buf [string!]]] what [char] len [int]
] zbl "zap_buff"
buff: {foo bar baz ^@ ^@ bing}
b-wrap: make struct! [buf [string!]] reduce [buff]
foreach c "REBOL^@" [
zap-buff b-wrap c length? buff
?? buff
]
The memory inside our BUFF in REBOL is actually manipulated by
the external library. Scary cool stuff.. :-)
-jeff