How to import and use C func(context_p ctx, char ** output)?

Q&A's, tips, howto's
Locked
jeremyc
Posts: 33
Joined: Wed Dec 06, 2006 3:33 am

How to import and use C func(context_p ctx, char ** output)?

Post by jeremyc »

How can I import and use:

int template_parse_string(context_p ctx, char *template_filename, char **output);

??? I know how to import and use C functions, but this one in particular is giving me problems with the char ** output parameter. This is a pointer to a string pointer. It's not an array of string pointers. Here's an example usage:

(set 't (context_init))
(context_set_value t "name" "John Doe")
(template_parse_string t "Hello, {{= name}}" output-value)
(println output-value) ;; Hello, John Doe

I've tried:

(set 'output-value "")
(template_parse_string t "..." (address output-value))

but when I run my newlisp code, all I get is a Bus error.

Any ideas?

Jeremy

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

You have to reserve space where template_parse_string() can deposit the pointer to the string, it is allocating.

Code: Select all

; reserve 4 bytes for the string address returned
; output-value now contains a 4-byte buffer filled with 0's

(set 'output-value (dup "\000" 4)) ; 

; when passing the buffer in output-value to a library imported
; C-function it will automatically pass the buffers address

(template_parse_string "Hell, {{ = name }}", output-value)

; output buffer now contains a 4-byte address to a string

(set 'result (get-string (get-int output-value)))

result => "Hello, John Doe"
A 'char * *' for one string address is the same as 'char * *' for an array of string pointers. The only difference is that in the array several pointers are packed one after the other. So basically in your example you deal with a string array with only one member. That means you could also take the array-code from
http://newlisp.org/CodePatterns.html#extending

and use it:

Code: Select all

(set 'result (get-string (get-int output-value)))

; is the same as the array code for one member "ld"

(set 'result (get-string (first (unpack "ld" output-value))))
but the first method is of course more streight forward in your case.

Lutz

ps: note also that template_parse_string() has allocated the memory space for the string. Who will free this memory? 'result' now contains a copy of the string generated, not the original string. That means if the library will clean up after the C-call everything will be fine for you because you have a copy in 'result'.

Locked