Hi Alfonso,

> I'm exploring Picolisp as a hobby for a while now, and I find it absolutely
> amazing. I'm experimenting with 'native', trying to make some bindings for
> SDL2 and OpenGL.

I assume you found the OpenGL library in the distribution too, right? Just for
the records, it is in "@lib/openGl.l".


> I want to call this OpenGL function with 'native':
> 
> void glShaderSource(
>     GLuint shader,
>     GLsizei count,
>     const GLchar **string,
>     const GLint *length)
> 
> I have a problem with the third argument. I can't figure out if and how a
> pointer to an array of string pointers can be passed to the function using
> 'native'.

An array of string pointers basically boils down to a structure in C.

However, this case is indeed tricky, because the string array must first be
created. I would call strdup() to get a list of pointers.

Assuming you have {"abc", "def", "ghi"), this would be

   (mapcar
      '((Str) (cons (native "@" "strdup" 'N Str) 8))
      '("abc" "def" "ghi") )

That is, it creates a list ((<pointer> . 8) (<pointer> . 8) (<pointer> . 8)).
The '8' values are needed for the 'native' struct definition (as the reference
says "a pair (num . cnt) where 'num' is stored in a field of 'cnt' bytes").

Note that you must also call free() on the results of strdup() when done.


> My other question is about the fourth argument. Is there a way (other than
> allocating some memory with 'malloc') so you can pass a C pointer to a
> Picolisp symbol's value using 'native'?

You can pass a pointer simply as a number. But this doesn't make sense here,
because where should that pointer come from?

So one way is to call 'malloc' as you said, but you can better let 'native' do
the alloction for you, as another structure which holds a single pointer and
which returns its value. The following passes the number 3 in a single-element
'int' array, receiving the possibly modified value in the variable 'Len':

   (Len (8 . I) -3)

If you are not interested in a return value, and just want to pass 3:

   (NIL (8) -3)


With all that, your function would be:

   (de glShaderSource (Shader Count Strings)
      (let
         (Lst
            (mapcar
               '((Str) (cons (native "@" "strdup" 'N Str) 8))
               Strings )
            Len (length Lst) )
         (native `*GlutLib "glShaderSource" NIL
            Shader
            Count
            (cons NIL (list (* 8 Len)) Lst)
            (list 'Len (8 . I) (- Len)) )
         (mapc '((X) (native "@" "free" NIL (car X))) Lst)
         Len ) )

You call it as (glShaderSource 3 4 '("abc" "def" "ghi")).

I haven't checked the OpenGL docs if this makes sense, and haven't tested the
above. It assumes that 'length' holds the number of strings in 'string' (and not
'count'!). And it assumes that you want to return the length in 'Len'. So the
above must perhaps be modified.

Indeed rather messy ;)

♪♫ Alex

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to