Passing a struct to a c-callout

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

Passing a struct to a c-callout

Mathieu Suen-2
Hi

I have a function hat take a list of struct as parameter:

typedef struct _dim {
        double x;
        double y;
        double w;
        double h;
} dim;

void
foo (...) {
        va_list args;
        ...
 }

In smalltalk I want to call this function so I have add a cCall wit variadic arguments:

foo [
        <cCall: 'foo' returning: #void args: #( #variadic )>
]

But it doesn't work.

Thanks for help.

        Mth




__________________________________________________
Do You Yahoo!?
En finir avec le spam? Yahoo! Mail vous offre la meilleure protection possible contre les messages non sollicités
http://mail.yahoo.fr Yahoo! Mail

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

Re: Passing a struct to a c-callout

Holger Freyther
On 02/17/2011 08:54 PM, Mathieu Suen wrote:
> Hi
>

> In smalltalk I want to call this function so I have add a cCall wit variadic arguments:
>
> foo [
> <cCall: 'foo' returning: #void args: #( #variadic )>
> ]

you will need to pass at least some argument...

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

Re: Passing a struct to a c-callout

Mathieu Suen-2
On Feb 17, 2011, at 9:03 PM, Holger Hans Peter Freyther wrote:

> On 02/17/2011 08:54 PM, Mathieu Suen wrote:
>> Hi
>>
>
>> In smalltalk I want to call this function so I have add a cCall wit variadic arguments:
>>
>> foo [
>> <cCall: 'foo' returning: #void args: #( #variadic )>
>> ]
>

oops sorry in fact I mean:

foo: list [
        <cCall: 'foo' returning: #void args: #( #variadic )>
]

> you will need to pass at least some argument...
>
> _______________________________________________
> help-smalltalk mailing list
> [hidden email]
> http://lists.gnu.org/mailman/listinfo/help-smalltalk


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

Re: Passing a struct to a c-callout

Holger Freyther
On 02/17/2011 09:29 PM, Mathieu Suen wrote:

> oops sorry in fact I mean:
>
> foo: list [
> <cCall: 'foo' returning: #void args: #( #variadic )>
> ]

could you create an example that works with the C library? e.g. printf (but
paolo was already adding a binding for that). And doesn't va_start need the
argument of the last type? this would mean that args should be something like
#(#something #variadic)?

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

Re : [Help-smalltalk] Passing a struct to a c-callout

Mathieu Suen-2
Hi

Eventually it is a bit more complicate. I thought I could make it simpler but
not.
The complete example is that I want to call a objective-c method that take a
struct as parameter:

@interface  NSWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
@end


The first parameter is a NSRect.
NSrect is a struct of basically 4 double on 64bit platform.
I call the method  #initWithContentRect:styleMask:backing:defer: using the
objective-c runtime:
void
objc_msgSend(id receiver, SEL msg, ...);

My cCall to objc_msgSend is define as follow:

ObjcRuntime class >> objcMsgSend: receiver selector: sel args: args [
    <cCall: 'objc_msgSend' returning: #cObject args: #( #cObject #cObject
#variadic )>
]

I have also define the struct NSRect as follow:

CStruct subclass: NSRect [
    <declaration: #( (#x #double) (#y #double) (#w #double) (#h #double) )>
]

But the invocation doesn't work:

nsRect :=  NSRect new.
  nsRect x value: 0.0.
  nsRect y value: 0.0.
  nsRect w value: 100.0.
  nsRect h value: 100.0
ObjcRuntime  objcMsgSend: nsWindow selector: initSeld args: {nsRect. 15. 2. 1}.



Thanks



----- Message d'origine ----

> De : Holger Hans Peter Freyther <[hidden email]>
> À : Mathieu Suen <[hidden email]>
> Cc : [hidden email]
> Envoyé le : Jeu 17 février 2011, 23h 01min 01s
> Objet : Re: [Help-smalltalk] Passing a struct to a c-callout
>
> On 02/17/2011 09:29 PM, Mathieu Suen wrote:
>
> > oops sorry in fact I  mean:
> >
> > foo: list [
> >     <cCall: 'foo'  returning: #void args: #( #variadic )>
> > ]
>
> could you create an  example that works with the C library? e.g. printf (but
> paolo was already  adding a binding for that). And doesn't va_start need the
> argument of the  last type? this would mean that args should be something like
> #(#something  #variadic)?
>




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

Re: Re : [Help-smalltalk] Passing a struct to a c-callout

Holger Freyther
On 02/18/2011 10:14 AM, Mathieu Suen wrote:

> CStruct subclass: NSRect [
>     <declaration: #( (#x #double) (#y #double) (#w #double) (#h #double) )>
> ]
>
> But the invocation doesn't work:
>
> nsRect :=  NSRect new.
>   nsRect x value: 0.0.
>   nsRect y value: 0.0.
>   nsRect w value: 100.0.
>   nsRect h value: 100.0
> ObjcRuntime  objcMsgSend: nsWindow selector: initSeld args: {nsRect. 15. 2. 1}.


ah okay, what is the error you get? do you get any? I think the objc runtime
on NeXT and GNU is different, but I will try your example (or come up with a
standalone example).

holger

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

Re : Re : [Help-smalltalk] Passing a struct to a c-callout

Mathieu Suen-2




----- Message d'origine ----

> De : Holger Hans Peter Freyther <[hidden email]>
> À : Mathieu Suen <[hidden email]>
> Cc : [hidden email]
> Envoyé le : Ven 18 février 2011, 10h 34min 55s
> Objet : Re: Re : [Help-smalltalk] Passing a struct to a c-callout
>
> On 02/18/2011 10:14 AM, Mathieu Suen wrote:
>
> > CStruct subclass: NSRect  [
> >     <declaration: #( (#x #double) (#y #double) (#w  #double) (#h #double) )>
> > ]
> >
> > But the invocation  doesn't work:
> >
> > nsRect :=  NSRect new.
> >   nsRect  x value: 0.0.
> >   nsRect y value: 0.0.
> >   nsRect w value:  100.0.
> >   nsRect h value: 100.0
> > ObjcRuntime   objcMsgSend: nsWindow selector: initSeld args: {nsRect. 15. 2.
>1}.
>
>
> ah  okay, what is the error you get? do you get any? I think the objc runtime
> on  NeXT and GNU is different, but I will try your example (or come up with  a
> standalone example).

I do not have error. instead I get those NSlog:
2011-02-18 10:46:56.986 gst[60568:903] NSWindow does not support nonactivating
panel styleMask 0x80
2011-02-18 10:46:56.988 gst[60568:903] NSWindow does not support HUD styleMask
0x2000

styleMask is 0x0F in my example.

>
> holger
>




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

Re: Re : Re : [Help-smalltalk] Passing a struct to a c-callout

Holger Freyther
On 02/18/2011 10:54 AM, Mathieu Suen wrote:

> I do not have error. instead I get those NSlog:
> 2011-02-18 10:46:56.986 gst[60568:903] NSWindow does not support nonactivating
> panel styleMask 0x80
> 2011-02-18 10:46:56.988 gst[60568:903] NSWindow does not support HUD styleMask
> 0x2000

my hint would be start gst. Then attach with gdb to it (gdb -p `pidof gst`)
and set a breakpoint in this objective c function, then execute your program
and use gdb to inspect your arguments. Maybe you see a pattern of what is
going wrong, e.g. the size of the SEL is wrong or such.

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

Re : [Help-smalltalk] Passing a struct to a c-callout

Mathieu Suen-2
Hi

I have break into the #initWithContentRect:styleMask:backing:defer: objective-c
method
and I get the first argument passed as a pointer in $rdx which is wrong since
the method expected to be in the stack (The size of the struct is more than
8byte and the ABI specify that it should be on the stack).

So I have made it explicitly be a struct:

    ObjcRuntime class >> specialObjcMsgSend: receiver selector: sel arg1: arg1
args: args [
    <cCall: 'objc_msgSend' returning: #cObject args: #( #cObject #cObject
#{NSRect} #variadic )>
    ]

NSRect being a subclass of CStruct...

But it doesn't work either.

-- Mathieu



----- Message d'origine ----

> De : Holger Hans Peter Freyther <[hidden email]>
> À : Mathieu Suen <[hidden email]>
> Cc : [hidden email]
> Envoyé le : Ven 18 février 2011, 11h 01min 40s
> Objet : Re: Re : Re : [Help-smalltalk] Passing a struct to a c-callout
>
> On 02/18/2011 10:54 AM, Mathieu Suen wrote:
>
> > I do not have error.  instead I get those NSlog:
> > 2011-02-18 10:46:56.986 gst[60568:903]  NSWindow does not support
>nonactivating
>
> > panel styleMask 0x80
> >  2011-02-18 10:46:56.988 gst[60568:903] NSWindow does not support HUD
>styleMask
>
> > 0x2000
>
> my hint would be start gst. Then attach with gdb to it  (gdb -p `pidof gst`)
> and set a breakpoint in this objective c function, then  execute your program
> and use gdb to inspect your arguments. Maybe you see a  pattern of what is
> going wrong, e.g. the size of the SEL is wrong or  such.
>




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

Re: Re : [Help-smalltalk] Passing a struct to a c-callout

Holger Freyther
On 02/18/2011 05:26 PM, Mathieu Suen wrote:
> Hi
>
> I have break into the #initWithContentRect:styleMask:backing:defer: objective-c
> method
> and I get the first argument passed as a pointer in $rdx which is wrong since
> the method expected to be in the stack (The size of the struct is more than
> 8byte and the ABI specify that it should be on the stack).

What prevents you from having the break point when you enter the objective c
world? too many other calls? you could try a conditional breakpoint?


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

Re : [Help-smalltalk] Passing a struct to a c-callout

Mathieu Suen-2
In reply to this post by Mathieu Suen-2
Hi All

After thcating with Paolo in irc. It reveal that c-call-out does not support call by value on struct.
Especially struct that is more than 8bit size on x64.

So I have made a example with FFI to see if that is in fact supported:

#include <stdlib.h>
#include <ffi.h>
#include <stdio.h>

typedef struct rect {

  double f;
  double g;
  double h;

} rect;

void
foo (rect argStruct)
{
  printf ("Receive a strcut by value f=%f, g=%f, h=%f\n", argStruct.f, argStruct.g, argStruct.h);
}


int
main ()
{
  int i;
  ffi_cif cif;
  ffi_type * arg[1];
  ffi_type structType;
  ffi_type * element[4];
  void * value[1];
  rect aStruct;
  arg[0] = &structType;
  structType.size = 0;
  structType.alignment = 0;

  value[0] = (void*)&aStruct;

  for (i = 0; i < 3; i++)
    element[i] = &ffi_type_double;
  element[3] = NULL;

  structType.elements = &element;

  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, arg) == FFI_OK)
    {
      aStruct.g = 5.5;
      aStruct.h = 3.4;
      aStruct.f = 9.0;
      ffi_call (&cif, foo, NULL, value);
    }
  else
    {
      return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}

compiled with:
gcc `pkg-config --libs libffi` `pkg-config --cflags libffi` testffi.c -o test

Testing that on OSX x64 shows that it is fine.
So other platform need to be test to see if that is working.

Thanks

        Mth




On Feb 18, 2011, at 5:26 PM, Mathieu Suen wrote:

> Hi
>
> I have break into the #initWithContentRect:styleMask:backing:defer: objective-c
> method
> and I get the first argument passed as a pointer in $rdx which is wrong since
> the method expected to be in the stack (The size of the struct is more than
> 8byte and the ABI specify that it should be on the stack).
>
> So I have made it explicitly be a struct:
>
>    ObjcRuntime class >> specialObjcMsgSend: receiver selector: sel arg1: arg1
> args: args [
>    <cCall: 'objc_msgSend' returning: #cObject args: #( #cObject #cObject
> #{NSRect} #variadic )>
>    ]
>
> NSRect being a subclass of CStruct...
>
> But it doesn't work either.
>
> -- Mathieu
>
>
>
> ----- Message d'origine ----
>> De : Holger Hans Peter Freyther <[hidden email]>
>> À : Mathieu Suen <[hidden email]>
>> Cc : [hidden email]
>> Envoyé le : Ven 18 février 2011, 11h 01min 40s
>> Objet : Re: Re : Re : [Help-smalltalk] Passing a struct to a c-callout
>>
>> On 02/18/2011 10:54 AM, Mathieu Suen wrote:
>>
>>> I do not have error.  instead I get those NSlog:
>>> 2011-02-18 10:46:56.986 gst[60568:903]  NSWindow does not support
>> nonactivating
>>
>>> panel styleMask 0x80
>>> 2011-02-18 10:46:56.988 gst[60568:903] NSWindow does not support HUD
>> styleMask
>>
>>> 0x2000
>>
>> my hint would be start gst. Then attach with gdb to it  (gdb -p `pidof gst`)
>> and set a breakpoint in this objective c function, then  execute your program
>> and use gdb to inspect your arguments. Maybe you see a  pattern of what is
>> going wrong, e.g. the size of the SEL is wrong or  such.
>>
>
>
>
>
> _______________________________________________
> help-smalltalk mailing list
> [hidden email]
> http://lists.gnu.org/mailman/listinfo/help-smalltalk

__________________________________________________
Do You Yahoo!?
En finir avec le spam? Yahoo! Mail vous offre la meilleure protection possible contre les messages non sollicités
http://mail.yahoo.fr Yahoo! Mail

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