How to pass NULL argument to C function

Started by csfreebird, December 07, 2014, 07:56:00 AM

Previous topic - Next topic

csfreebird

Hi, I want to pass a NULL argument to one C function.

The C function looks like so:

#define BCON_NEW(...)
   bcon_new (NULL, __VA_ARGS__, NULL)


In newlisp , I write:

(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:
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?

ryuo

#1
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.

Lutz

#2
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):

> (import "libc.dylib" "printf")
printf@7FFF90EBA930
> (printf "%s %d %s" "hello" 123 "worldn")
hello 123 world
16
>


on Windows (32-bit):

> (import "msvcrt.dll" "printf")
printf@77C4186A
> (printf "%s %d %sn" "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.

csfreebird

#3
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.