Page 1 of 1

How to pass NULL argument to C function

Posted: Sun Dec 07, 2014 3:56 pm
by csfreebird
Hi, I want to pass a NULL argument to one C function.
The C function looks like so:

Code: Select all

#define BCON_NEW(...) \
   bcon_new (NULL, __VA_ARGS__, NULL)
In newlisp , I write:

Code: Select all

(set 'bson-lib "/usr/local/lib/libbson-1.0.so")
;; @Import bson_t * bcon_new (void *unused,...) BSON_GNUC_NULL_TERMINATED;
(import bson-lib "bcon_new" "void*" "void*" "char*" "char*")

;; @syntax (mongo:bcon-new arg1 arg2)
;; @return the point of bson_t
(define (bcon-new arg1 arg2)
  (println arg1 "|" arg2)
  (bcon_new nil arg1 arg2)
  )

(set 'query-ptr (mongo:bcon-new "stats" "test"))
I got missing argument error:

Code: Select all

stats|test

ERR: missing argument
called from user defined function mongo:bcon-new
I try to pass nil, but it seems wrong. How can I do it?

Re: How to pass NULL argument to C function

Posted: Sun Dec 07, 2014 9:48 pm
by ryuo
To pass a NULL pointer, you would have to use its integer value, 0. But there is another issue. You are trying to map a variadic C function. These may not be usable from the newLISP FFI API, but it appears libFFI supports them. The newLISP documentation doesn't appear to mention anything about variadic functions, so I think it is reasonable to conclude that they are not supported. However, only Lutz probably knows for sure.

The problem is that variadic C functions may or may not be callable in the same way as a regular C function. To the best of my knowledge, this is an "implementation detail" and therefore may not be portable. In other words, your current function import may not work on other newLISP platforms, if it even works on the current platform.

If I am correct, then here are some ideas that may help you work around this potential issue: use an alternative normal C function that can achieve the same results or write shared library code to wrap the variadic function call within a normal C function.

Re: How to pass NULL argument to C function

Posted: Sun Dec 07, 2014 11:23 pm
by Lutz
When using the simple FFI - without declaring types - variadic functions work fine as long as no floats are involved:

on Mac OS X (64-bit):

Code: Select all

> (import "libc.dylib" "printf")
printf@7FFF90EBA930
> (printf "%s %d %s" "hello" 123 "world\n")
hello 123 world
16
> 
on Windows (32-bit):

Code: Select all

> (import "msvcrt.dll" "printf")
printf@77C4186A
> (printf "%s %d %s\n" "hello" 123 "world")
hello 123 world
16
>
the return value '16' is the number of characters printed.

On 32-bit newLISP, all args would be passed as 32-bit entities (pointers and integer values), on 64-bit newLISP as 64-bit entities.

Re: How to pass NULL argument to C function

Posted: Mon Dec 08, 2014 5:31 pm
by csfreebird
Thanks. I know to pass 0 as NULL argument now and how to use variadic function.
I still have some questions when developing mongodb.lsp based on mongodb c driver.
Will ask them in other threads.