2016-04-11 15:10 GMT+02:00 Esteban Lorenzano <esteba...@gmail.com>:

>
> > On 11 Apr 2016, at 06:24, Thibault Raffaillac <
> thibault.raffail...@inria.fr> wrote:
> >
> >>> 1) Declare a class variable
> >>>
> >>> MyClass class>>initialize
> >>>     INT_PTR := FFIExternalValueHolder ofType: ?int?.
> >>
> >> as a larger explanation, this will create an anonymous subclass to keep
> ?int?
> >> values, than later you can use as a type in your  function call. Some
> people
> >> would call this obscure, but is a good way of solving this problem (I
> >> adopted it from old NB).
> >> If you want to have a named class instead an anonymous class, you can
> just
> >> subclass FFIExternalValueHolder:
> >>
> >> FFIExternalValueHolder subclass: #MyIntPtr
> >>
> >> and then implement typeDecl class method
> >>
> >> MyIntPtr class>>typeDecl
> >>      ^ ?int'
> >>
> >> and this will work as the anonymous class
> >
> > The second option is definitely what I want.
>
> Personally my option would be to put my types in a class pool and use
> them, not to extend…
> but option is there so you can choose what you want :)
>
> > I am trying to expose a function returning several ints, as in
> SDL2>>mouseStateX: y: (excluding the possibility to return a Point).
> > However I would rather not define my own int holder, can't we have
> generic holders to rely on?
>
> I will not add for the moment that predefined types value holders… We
> would need to add one for each type we support to be consistent, and
> document it, and add tests.
> And btw… you do have a generic holder… is just that you need to refine it
> to what you want :)
> You could always use a ByteArray and took values later (some functions in
> Athens do it like that). The advantage of this approach (using plain
> ByteArrays) is that you do not need to change function signature at the
> cost of needing to do manually what the value holder does for you.
>

Hi Esteban,

is this the way it should be done for Strings ?
For example, old NBOpenGL had this Windows method to get the Window Title:

getWindowText: hWnd buffer: lpString bufferSize: nMaxCount
        <primitive: #primitiveNativeCall module: #NativeBoostPlugin>

        ^self nbCall: #(int GetWindowTextA(HWND hWnd, char* lpString, int
nMaxCount))
            module: #user32

called as:

getWindowText
    | len str |
    str := ByteString new: 1000.
    len := self getWindowText: self buffer: str bufferSize: 1000.
    ^ str first: len.


When I just modify the ffiCall to

getWindowText: hWnd buffer: lpString bufferSize: nMaxCount

    ^self ffiCall: #(int GetWindowTextA(HWND hWnd, char* lpString, int
nMaxCount)) module: #user32

I get just an empty String.

But If I call it with:

| len str |
    str := ByteArray new: 1000.
    len := self getWindowText: self buffer: str bufferSize: 1000.
    ^ String fromByteArray: (str first: len).

I get the real string text. Is this the way to go?




>
> My advise is that you go with what you need, we can consider add
> predefined value holders later.
>
> Esteban
>
> >
> > Thibault
> >
>
>
>

Reply via email to