[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-users] Re: collecting binary strings from c code to scheme
From: |
Jason Meade |
Subject: |
[Chicken-users] Re: collecting binary strings from c code to scheme |
Date: |
Sun, 6 Apr 2008 14:37:25 -0700 |
On Apr 5, 2008, at 8:44 PM, Jason Meade wrote:
Hi all,
I'm working on a C module that I wish to expose to scheme. So far I
have been able to transfer null terminated strings from C to scheme
no problem. Now I wish to transfer binary strings from C to scheme.
I see that there is a C_string function that appears to do the
trick, unfortunately I am not getting the results I would like.
Below is my code. Perhaps someone could suggest a way to get the
binary string data from C to scheme correctly? I'm more than
willing to entertain non-string solutions, such as transferring
data as lists if need be. (Help with that is also appreciated)
=== handle.c ===
C_word PFBuffer_scm_delete_mark (int handle)
{
C_word *ptr;
C_word str;
if (handle >= 0 && handle < PFBuffer_MAX_HANDLES) {
PFBuffer* buf = *(PFBuffer_handles + handle);
if (buf) {
PFBuffer_delete_mark (buf);
ptr = C_alloc(C_SIZEOF_STRING(buf->copytext_length));
str = C_string(&ptr,buf->copytext_length,buf->copytext);
}
}
return str;
}
=== pfbuffer.scm ===
#>
extern C_word PFBuffer_scm_delete_mark (int);
<#
(define pfbuffer:delete-marked-text
(foreign-lambda scheme-object PFBuffer_scm_delete_mark int))
=== scheme repl ===
#;1> (require 'pfbuffer)
; loading /opt/local/lib/chicken/1x/pfbuffer.so ...
#;2> (define buf (pfbuffer:alloc))
#;3> (pfbuffer:attach-and-read-file buf "pfbuffer.so")
69488
#;4> (pfbuffer:set-point-and-mark buf 0)
0
#;5> (pfbuffer:set-point-and-mark buf 20)
20
#;6> (pfbuffer:delete-marked-text buf)
#(#<procedure (a2315 . rs608)>)
#;7>
Obviously I am not expecting to receive a procedure as a result,
but just for fun, let's see what happens if I capture and run the
proc.
#;7> (pfbuffer:set-point-and-mark buf 0)
0
#;8> (pfbuffer:set-point-and-mark buf 20)
20
#;9> (define func (pfbuffer:delete-marked-text buf))
#;10> (func)
Error: call of non-procedure: "\x1c\x04\x00\x00
\x00\x00\x00\x01\x00\x00\x00H\x01\x00\x00__TE"
Call history:
<syntax> (func)
<eval> (func) <--
#;10>
The function blows up, but it *seems* that I was at least able to
fetch my 20 binary characters. It seems like I am close to figuring
this out. Any help that anyone can give would be very much
appreciated.
Thanks,
-Jason
I got it working. I ended up using a callback function that I
patterned after an example in the manual. Here's the code:
=== handle.c ===
C_word PFBuffer_scm_delete_mark (int handle)
{
C_word str;
C_word *ptr;
if (handle >= 0 && handle < PFBuffer_MAX_HANDLES) {
PFBuffer* buf = *(PFBuffer_handles + handle);
if (buf) {
PFBuffer_delete_mark (buf);
ptr = C_alloc(C_SIZEOF_STRING(buf->copytext_length));
str = C_string(&ptr,buf->copytext_length,buf->copytext);
}
}
return scheme_object(str);
}
=== pfbuffer.scm ===
#>
extern C_word PFBuffer_scm_delete_mark (int);
<#
(define pfbuffer:delete-marked-text
(foreign-lambda scheme-object PFBuffer_scm_delete_mark int))
;; A generic call-in function intended to be used from C code
;; that will allow external C code to pass Scheme objects as return
values.
(define-external (scheme_object (scheme-object xyz)) scheme-object
xyz)
=== scheme repl ===
#;1> (require 'pfbuffer)
; loading /opt/local/lib/chicken/1x/pfbuffer.so ...
#;2> (define buf (pfbuffer))
#;3> (pfbuffer:attach-and-read-file buf "pfbuffer.so")
74104
#;4> (pfbuffer:set-point-and-mark buf 0)
0
#;5> (pfbuffer:set-point-and-mark buf 20)
20
#;6> (let ((txt (pfbuffer:delete-marked-text buf)))
(list txt (string-length txt)))
("\x1c\x04\x00\x00
\x00\x00\x00\x01\x00\x00\x00H\x01\x00\x00__TE" 20)
#;7>
If there is a way to accomplish this without the callback then I
would love to hear it. If not, then this solution seems to work fine
for now.
Thanks
-Jason