Page 1 of 1

How to pass a newlisp string to C function as uint8_t* arg

Posted: Mon Dec 08, 2014 5:38 pm
by csfreebird
The existing C function is:

Code: Select all

bson_t * bson_new_from_json (const uint8_t* data, ssize_t len, bson_error_t  *error);
I import it in newlisp:

Code: Select all

(import bson-lib "bson_new_from_json" "void*" "void*" "unsigned int" "void*")
;; I also tried to use char* instead
;; (import bson-lib "bson_new_from_json" "void*" "char*" "unsigned int" "void*")

;; @syntax (mongo:bson-new-from-json json-str)
;; @return the pointer of bson_t
(define (bson-new-from-json json-str)
  (bson_new_from_json json-str (length json-str) 0)
  )
Now when I try to use bson_new_from_json function, always get 0 value returned.

Code: Select all

(load "mongo.lsp")
(set 'cmd-str "{stats:true}")
"{stats:true}"
> (mongo:bson-new-from-json cmd-str)
0

Re: How to pass a newlisp string to C function as uint8_t* a

Posted: Wed Dec 10, 2014 11:59 am
by ryuo
First of all, there's an issue with how you imported the function. You import it as "unsigned int" when "ssize_t" is the same size as "size_t", but signed instead of unsigned. To map this to the proper type, it depends on the platform. Most POSIX implementations on x86 that I know of make ssize_t and size_t the same size as a pointer, which also happens to be the same as long and unsigned long in these cases. IIRC, there's only one C implementation that I know of that breaks this assumption. Win32 vs Win64. It's only true for Win32. Win64 does not change the size of integer primitives (char, short, int, long) from what they are in Win32. You would have to use long long if you wanted this to work on Win64.

This may be a contributing factor as to why NULL is returned, but it would help if you could define the bson_error_t type and then retrieve the actual error message.

From what I can determine, the type necessary is this:

Code: Select all

typedef struct
{
   uint32_t domain;
   uint32_t code;
   char     message[504];
} bson_error_t;
This can be converted to the following pack format: "lu lu s504". I would not recommend trying to use struct with this, as that doesn't really handle string arrays well.

So, if you could determine the actual error, that would help you find out what to do next.