C Callouts issue

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

C Callouts issue

Stephen Woolerton
Hi everyone,

I've been writing a tutorial on C Callouts from GNU Smalltalk, and am
trying to get a couple of C callout scenarios to work. I'm having
difficulty when there is an argument in the callout, which is a
pointer.

Given a C header of :-
----
struct       Note {
    int         id;
    char*       memo;     //variable length
    long        modified; //timestamp
};
extern struct Note* newBlankNote(unsigned int *resultCode);
extern unsigned int initializeNote(struct Note *note);
----


I created a Smalltalk class with mappings as follows:
----
CStruct subclass: CNote [
         <declaration: #( (#id  #int)
                          (#memomemo #string)
                          (#modified #long))>

   CNote class >> newBlankNote: retVal [
      <cCall: 'newBlankNote' returning: #{CNote} args: #(#{CObject})>
   ]
   initializeNote: aNote [
      <cCall: 'initializeNote' returning: #uint args: (#self)>
   ]
]
----

And inside the smalltalk script, I have this...
| note retVal |
retVal := 0.
note := CNote newBlankNote: retVal.


The error I'm receiving is...
./ccall2.st:31: Attempt to pass an instance of SmallInteger as a void *
Object: CFunctionDescriptor new: 1 "<0x7f935dbc4a10>" error: primitive
operation failed
SystemExceptions.PrimitiveFailed(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.PrimitiveFailed class(Exception class)>>signal
(ExcHandling.st:151)
CFunctionDescriptor(Object)>>primitiveFailed (Object.st:1349)
CFunctionDescriptor(CCallable)>>callNoRetryFrom:into: (CCallable.st:179)
CFunctionDescriptor(CCallable)>>callInto: (CCallable.st:166)
CNote class>>newBlankNote: (ccall2.st:1)
UndefinedObject>>executeStatements (ccall2.st:30)
---------------

If I modify the scripts so that retVal is a standard "unsigned int" and
not a pointer, this callout works.

Also: if I try to run this code...
| note retVal |
note := CNote new.
retVal := note initializeNote.

I'm getting a similar error, namely...
./ccall2.st:36: Attempt to pass an instance of ValueHolder as a void *
Object: CFunctionDescriptor new: 1 "<0x7f935dbc6aa0>" error: primitive
operation failed
SystemExceptions.PrimitiveFailed(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.PrimitiveFailed class(Exception class)>>signal
(ExcHandling.st:151)
CFunctionDescriptor(Object)>>primitiveFailed (Object.st:1349)
CFunctionDescriptor(CCallable)>>callNoRetryFrom:into: (CCallable.st:179)
CFunctionDescriptor(CCallable)>>callInto: (CCallable.st:166)
CNote>>initializeNote (ccall2.st:1)
UndefinedObject>>executeStatements (ccall2.st:35)

-----------------
The full code (C library, C test program, and smalltalk script) is
viewable at this URL:
http://artinamessage.wordpress.com/2013/07/07/gnu-smalltalk-with-c-callouts-2/

I'm using GNU Smalltalk 3.2.5 on a copy of Gentoo Linux, and if someone
could
be so kind as to assist me finding the problem, this will be much
appreciated.

Regards
Stephen

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callouts issue

Holger Freyther
On Tue, Jul 09, 2013 at 01:26:12PM +1200, Stephen Woolerton wrote:
> Hi everyone,

Good Morning,

> I've been writing a tutorial on C Callouts from GNU Smalltalk, and am
> trying to get a couple of C callout scenarios to work. I'm having
> difficulty when there is an argument in the callout, which is a
> pointer.


ah great. My memory on C Callouts is fading (I started with creating
bindings for the Osmocore libraries but then stopped and had more
important things).

> struct       Note {
>    int         id;
>    char*       memo;     //variable length
>    long        modified; //timestamp
> };
> extern struct Note* newBlankNote(unsigned int *resultCode);
> extern unsigned int initializeNote(struct Note *note);


>   CNote class >> newBlankNote: retVal [
>      <cCall: 'newBlankNote' returning: #{CNote} args: #(#{CObject})>

OKay, so you would like to have something like a intOut.. or does
CInt help here? Sorry, I am guessing. Or something like #selfSmallalk?


sorry for not being of more help right now
        holger

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callouts issue

Stephen Woolerton
> OKay, so you would like to have something like a intOut.. or does
> CInt help here? Sorry, I am guessing. Or something like #selfSmallalk?
>
> holger
Thanks holger.

I had two issues in the last post.
One was a typo, the call to initializeNote was missing a # in the
definition, i.e. #(#self)

However, I am still working on how to pass a "pointer to an unsigned
int" as a C callout. The page
http://www.gnu.org/software/smalltalk/manual/gst.html#C-data-types shows
how to pass a pointer to a scalar when in a struct, e.g. (#example (#ptr
#long)).
So I changed my script to have a similar definition:

   CNote class >> newBlankNote: retVal [
      <cCall: 'newBlankNote' returning: #{CNote} args: #((#ptr #uint)>
   ]

And here is the result when the library is called... (the first two
lines come from printf statements inside the C library. The second line
shows that the pointer was not actually passed into the library, it is nil)

  Inside newBlankNote: Size in bytes allocated to struct 'Note': 8
  Inside newBlankNote: resultCode pointer: [(nil)]
./ccall2.st:30: Aborted
./ccall2.st:30: Error occurred while not in byte code interpreter!!
/usr/local/lib64/libgst.so.7(+0x71ca7)[0x7f8d8d996ca7]
/lib64/libc.so.6(+0x37c50)[0x7f8d8ceb2c50]
/lib64/libc.so.6(gsignal+0x35)[0x7f8d8ceb2bd5]
/lib64/libc.so.6(abort+0x17b)[0x7f8d8ceb404b]
/usr/local/lib64/libgst.so.7(+0x2c9bb)[0x7f8d8d9519bb]
/usr/lib64/libsigsegv.so.2(+0xe7c)[0x7f8d8cc77e7c]
/lib64/libc.so.6(+0x37c50)[0x7f8d8ceb2c50]
/home/stephenw/devel_gst/ccall2/bug1/libccall2.so(newBlankNote+0x74)[0x7f8d8b7196d0]
/usr/lib64/libffi.so.6(ffi_call_unix64+0x4c)[0x7f8d8ca74ecc]
/usr/lib64/libffi.so.6(ffi_call+0x19d)[0x7f8d8ca7489d]
Aborted

Regards
Stephen



_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callouts issue

Gwenaël Casaccio
On 10/07/2013 08:15, Stephen Woolerton wrote:

>> OKay, so you would like to have something like a intOut.. or does
>> CInt help here? Sorry, I am guessing. Or something like #selfSmallalk?
>>
>>     holger
> Thanks holger.
>
> I had two issues in the last post.
> One was a typo, the call to initializeNote was missing a # in the
> definition, i.e. #(#self)
>
Hi,

You need to pass a CUInt object and not an integer since the function
expect a pointer.

| note retVal |
retVal := CUInt value: 0.
note := CNote newBlankNote: retVal.

Gwen

> However, I am still working on how to pass a "pointer to an unsigned
> int" as a C callout. The page
> http://www.gnu.org/software/smalltalk/manual/gst.html#C-data-types 
> shows how to pass a pointer to a scalar when in a struct, e.g.
> (#example (#ptr #long)).
> So I changed my script to have a similar definition:
>
>   CNote class >> newBlankNote: retVal [
>      <cCall: 'newBlankNote' returning: #{CNote} args: #((#ptr #uint)>
>   ]
>
> And here is the result when the library is called... (the first two
> lines come from printf statements inside the C library. The second
> line shows that the pointer was not actually passed into the library,
> it is nil)
>
>  Inside newBlankNote: Size in bytes allocated to struct 'Note': 8
>  Inside newBlankNote: resultCode pointer: [(nil)]
> ./ccall2.st:30: Aborted
> ./ccall2.st:30: Error occurred while not in byte code interpreter!!
> /usr/local/lib64/libgst.so.7(+0x71ca7)[0x7f8d8d996ca7]
> /lib64/libc.so.6(+0x37c50)[0x7f8d8ceb2c50]
> /lib64/libc.so.6(gsignal+0x35)[0x7f8d8ceb2bd5]
> /lib64/libc.so.6(abort+0x17b)[0x7f8d8ceb404b]
> /usr/local/lib64/libgst.so.7(+0x2c9bb)[0x7f8d8d9519bb]
> /usr/lib64/libsigsegv.so.2(+0xe7c)[0x7f8d8cc77e7c]
> /lib64/libc.so.6(+0x37c50)[0x7f8d8ceb2c50]
> /home/stephenw/devel_gst/ccall2/bug1/libccall2.so(newBlankNote+0x74)[0x7f8d8b7196d0]
>
> /usr/lib64/libffi.so.6(ffi_call_unix64+0x4c)[0x7f8d8ca74ecc]
> /usr/lib64/libffi.so.6(ffi_call+0x19d)[0x7f8d8ca7489d]
> Aborted
>
> Regards
> Stephen
>
>
>
> _______________________________________________
> help-smalltalk mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-smalltalk


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callouts issue

Stephen Woolerton
On 10/07/13 8:07 PM, Gwenaël Casaccio wrote:

> Hi,
>
> You need to pass a CUInt object and not an integer since the function
> expect a pointer.
>
> | note retVal |
> retVal := CUInt value: 0.
> note := CNote newBlankNote: retVal.
>
> Gwen
>
Much appreciated Gwen, exactly what was needed.

And I've updated the C callout tutorial...
http://artinamessage.wordpress.com/2013/07/07/gnu-smalltalk-with-c-callouts-2/

Regards
Stephen

_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk