How to send big string to library and back?
[1/12] from: petr:krenzelok:trz:cz at: 16-Apr-2001 2:26
Hi,
as I am not fluent in C programming, I asked my friend to set-up GNU C on my
desktop and notebook. I showed him Rebol library interface, and asked him,
if he would be able to maintain image data inside the library space. Our
device (CCD camera) returns pixel information as two bytes values 0 to 65535
(#FFFF). ("0" is converted to ^@, if I convert values to 'to-string ones)
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.
So is there a way how to send string of concrete length to library space and
back, without the fear that "0" char will end my string by accidance?
Has anyone tried that? Or maybe Jeff could clarify?
Thanks,
-pekr-
[2/12] from: al:bri:xtra at: 16-Apr-2001 17:47
Sounds like you need a unsigned integer array. Try this in C:
const unsigned uWidth = 500;
const unsigned uHeight = 400;
const unsigned uSize = uWidth * uHeight;
unsigned uCamera[uSize];
You can put values into the array like:
uCamera[0] = 0x0010; // First position in array.
uCamera[1] = 0x0000;
//...
uCamera[uSize - 1] = 0xF123; //Last position in array.
I hope that helps!
Andrew Martin
ICQ: 26227169 http://members.nbci.com/AndrewMartin/
[3/12] from: petr:krenzelok:trz:cz at: 16-Apr-2001 10:14
----- Original Message -----
From: "Andrew Martin" <[Al--Bri--xtra--co--nz]>
To: <[rebol-list--rebol--com]>
Sent: Monday, April 16, 2001 7:47 AM
Subject: [REBOL] Re: How to send big string to library and back?
> Sounds like you need a unsigned integer array. Try this in C:
> const unsigned uWidth = 500;
<<quoted lines omitted: 7>>
> uCamera[uSize - 1] = 0xF123; file://Last position in array.
> I hope that helps!
I will pass it to my friend who will code in C for us. However - how should
I put Rebol string datatype into array of unsigned values??? I don't want to
taky any time consuming operation in Rebol, as that's exactly the reason why
I want to call library function - the speed ...
The simple question once again :-) - Is string sent to library interface
being automatically ended once "0" char appears in it? (and vice versa - the
same for string returning from library interface to Rebol?)
Thanks,
-pekr-
[4/12] from: al:bri:xtra at: 16-Apr-2001 20:29
> Is string sent to library interface being automatically ended once "0"
char appears in it? (and vice versa - the same for string returning from
library interface to Rebol?)
Don't know for sure. I believe so, based on earlier information on Ally
list. Example, was passing rebol strings to Windows message box, IIRC. The
example script had no special problem with zero terminators, 'cause Rebol
automatically put them in.
> how should I put Rebol string datatype into array of unsigned values?
I don't know where Rebol, the camera port and the C program fit in all this.
Is it like:
Camera -> Serial Port -> Rebol Script -> C program/library
?
If so, just pass the string (auto converted to zero terminated C string on
Windows, IIRC) to the C program/library.
Andrew Martin
Who's C has grown very rusty.
ICQ: 26227169 http://members.nbci.com/AndrewMartin/
[5/12] from: carl:rebol at: 16-Apr-2001 1:38
No. REBOL does not use the null to terminate its strings. But, best to use
Binary! datatype, not a string. Then you can just do a PROBE to debug the
binary data. Handy.
-Carl
[6/12] from: petr:krenzelok:trz:cz at: 16-Apr-2001 11:13
----- Original Message -----
From: "Andrew Martin" <[Al--Bri--xtra--co--nz]>
To: <[rebol-list--rebol--com]>
Sent: Monday, April 16, 2001 10:29 AM
Subject: [REBOL] Re: How to send big string to library and back?
> > Is string sent to library interface being automatically ended once "0"
> char appears in it? (and vice versa - the same for string returning from
<<quoted lines omitted: 5>>
> > how should I put Rebol string datatype into array of unsigned values?
> I don't know where Rebol, the camera port and the C program fit in all
this.
> Is it like:
>
> Camera -> Serial Port -> Rebol Script -> C program/library
Camera -> Embedded Ethernet (TCP/IP) -> REBOL Script -> C library
I know exact size of image of course, so I also know certain size of string.
Maybe I just can't express myself correctly, so I will try once again:
I expect Rebol to put zero terminator at the end of the string, but let me
show a small example:
1)
image-data: "abcdefg"
rebol-2-library: "abcdefg0" ;OK
2)
image-data: "abc0defg" ; note "0" char as valid pixel value!
a) rebol-2-library: "abc0defg0" ;OK
b) rebol-2-library: "abc0" ; wrong - Rebol found 0 char inside fo script and
cuts the rest of image data ...
So, what will Rebol do? a) or b) ?
Excuse my lame questions, I am no C coder :-)
Thanks,
-pekr-
[7/12] from: petr:krenzelok:trz:cz at: 16-Apr-2001 11:32
----- Original Message -----
From: "Carl Sassenrath" <[carl--rebol--com]>
To: <[rebol-list--rebol--com]>
Sent: Monday, April 16, 2001 10:38 AM
Subject: [REBOL] Re: How to send big string to library and back?
> No. REBOL does not use the null to terminate its strings. But, best to use
> Binary! datatype, not a string. Then you can just do a PROBE to debug the
> binary data. Handy.
Yes, so far it seems to me we will use /binary ports to receive binary data
representation. But how do I send binary rebol datatype to library? Library
docs don't seem to cover binary! datatype as an option ...
-pekr-
[8/12] from: al:bri:xtra at: 16-Apr-2001 21:45
pekr, is the camera image binary data or is it encoded into characters?
I get the impression that it's binary. So it shouldn't be passed as a string
to the C library. Better would be as a unsigned array as I described
earlier.
It's possible to append a null value to Rebol strings like:
>> s: "123"
== "123"
>> append s "^(00)"
== "123^@"
so as to fool the C library that this is a proper C string. Just don't make
it larger in the C library!
Andrew Martin
ICQ: 26227169 http://members.nbci.com/AndrewMartin/
[9/12] from: robert:muench:robertmuench at: 16-Apr-2001 15:36
> -----Original Message-----
> From: [rebol-bounce--rebol--com] [mailto:[rebol-bounce--rebol--com]]On Behalf Of
> Andrew Martin
> Sent: Monday, April 16, 2001 11:46 AM
> To: [rebol-list--rebol--com]
> Subject: [REBOL] Re: How to send big string to library and back?
Hi, if you know the size, why don't you send the size as an extra parameter
to/from the library and the pointer/array/... of your binary data as the
second? If it's possible to make it easy, just keep it easy ;-)) Robert
[10/12] 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
[11/12] from: petr:krenzelok:trz:cz at: 16-Apr-2001 17:04
----- Original Message -----
From: "Robert M. Muench" <[robert--muench--robertmuench--de]>
To: <[rebol-list--rebol--com]>
Sent: Monday, April 16, 2001 3:36 PM
Subject: [REBOL] Re: How to send big string to library and back?
> > -----Original Message-----
> > From: [rebol-bounce--rebol--com] [mailto:[rebol-bounce--rebol--com]]On Behalf Of
<<quoted lines omitted: 3>>
> > Subject: [REBOL] Re: How to send big string to library and back?
> Hi, if you know the size, why don't you send the size as an extra
parameter
> to/from the library and the pointer/array/... of your binary data as the
> second? If it's possible to make it easy, just keep it easy ;-)) Robert
What? You want to tell me, that I can pass pointer to rebol word (pointing
to/"containing" binary data) to the library, and manipulate such data
directly via library interface? Eh, that's imo impossible as it would be
easy. IIRC we are not able to manipulate rebol datatypes data from external
environment, or am I wrong?
-pekr-
[12/12] from: petr:krenzelok:trz:cz at: 16-Apr-2001 19:43
----- Original Message -----
From: <[jeff--rebol--net]>
To: <[rebol-list--rebol--com]>
Sent: Monday, April 16, 2001 4:44 PM
Subject: [REBOL] Re: How to send big string to library and back?
> Howdy, Petr:
> > But my friend asked me a question I am not able to answer
<<quoted lines omitted: 15>>
> library routine that is expecting a pointer to any kind of
> data.
Jeff, thanks for the answer, I passed it to my Linux guru coleague :-)
I have to state that my knowledge of C is - well - I know the language
exists, that's all, so be patient with my questions, please :-)
Question to your above paragraph - Can I send "pointer" to rebol data into
library? I thought I will have to pass whole string to library = copying the
data in memory. If I can do following, it is cool:
1) having rebol word referring to string/binary data (rebol-string:
abcdefgh
)
2) defining routine which sends "pointer" to 'rebol-string into library ..
3) manipulating data referred by 'rebol-string in memory from library space
4) returning from routine, which means operation upon my image data is over
(from the library space perspective) and I can continue to work upon my
'rebol-string
in rebol environment ...
> The only hitch is having that memory come back. The way
> COMMAND works now is that if you have a return type of
COMMAND = View/Pro library interface? Does have View/Pro library interface
the same capabilities? (I hope so :-)
> string! (or char*) then REBOL/Command must find the null
> terminator-- otherwise you have some unbounded string
<<quoted lines omitted: 3>>
> in the external routine, I recommend: 1. doing all your
> manipulations on that data from REBOL first.
All I need is to find optimal minimum and maximum in image data (rebol
minimum-of and maximum-of are not enough, as our image can contain "hot"
pixels, so range set could be inaccurete ... I would need some
maximum-of/exclude date [#{FFFF} #{FFFE}]), compute at least linear look-up
table (simply said to divide all values by some computed constant ... it's a
pity 'change/dup can't accept some simple math expression to be evaluated
upon each element of data array), and divide pixel values to get displayable
value (bitmap). Rebol iteration is slow for that ....
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".
Well, :-) I will have to stop wasting your time. My understanding of above
is just currently in theoretical level, I will have to ask my friend to
implement basic scenario and once I do some coding in C myself, I will be
able to discuss possibilities further ...
> > For example:
> // FOR UNIX --
<<quoted lines omitted: 3>>
> 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"
<<quoted lines omitted: 10>>
> The memory inside our BUFF in REBOL is actually manipulated by
> the external library. Scary cool stuff.. :-)
Sounds cool. And once I will understand it fully, it will sound even much
cooler :-)
Thanks anyway,
-pekr-
PS: is that only me or do you see global world Rebolution started by View
1.1 release? :-)
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted