Thursday, February 12, 2015

C: JSON String Generation Using Jansson Library

In keeping up with the Arduino-to-RPi NRF24L01+ (DIY Belkin Wemo project), I move on to testing out libraries that can parse and generate JSON strings. The library I'm using is Jansson as it seemed to have gotten quite a bit of praise of all the 20-30ish listed on the JSON.org.

This time, I'm simply testing out JSON string generation and leaving off the parsing to next time. Arduino side will also need a JSON library but that will come later.

I'm using Xubuntu 14.10 and good thing Ubuntu has the Jansson library in the repository so I'm saving time by installing from apt-get:

sudo apt-get install libjansson-dev

Create a new c file. Jansson JSON object has the type json_t. To put anything (JSONObject, JSONArray, string, or integer), the call is json_object_set_new(). Here's a very simple example I whipped up.

#include <stdio.h>
#include <string.h>
#include <jansson.h>

int main(void) {
  
  char* s = NULL;
  
  json_t *root = json_object();
  json_t *json_arr = json_array();
  
  json_object_set_new( root, "destID", json_integer( 1 ) );
  json_object_set_new( root, "command", json_string("enable") );
  json_object_set_new( root, "respond", json_integer( 0 ));
  json_object_set_new( root, "data", json_arr );
  
  json_array_append( json_arr, json_integer(11) );
  json_array_append( json_arr, json_integer(12) );
  json_array_append( json_arr, json_integer(14) );
  json_array_append( json_arr, json_integer(9) );
  
  s = json_dumps(root, 0);
  
  puts(s);
  json_decref(root);
  
 return 0;
}

The code is pretty self-explanatory. I create a root JSON Object and an JSON Array that I will be appending to one of the entries in the JSON Object.

  json_t *root = json_object();
  json_t *json_arr = json_array();

Then I add 4 entries to this JSON Object: "destID", "command", "respond", and "data". The first three are of types integer (1), string ("enable"), and integer (0). The last one is of a JSON Array that I've created earlier.

  json_object_set_new( root, "destID", json_integer( 1 ) );
  json_object_set_new( root, "command", json_string("enable") );
  json_object_set_new( root, "respond", json_integer( 0 ));
  json_object_set_new( root, "data", json_arr );

I've yet added any array elements in the JSON Array. The following lines add four integer values to the array.

  json_array_append( json_arr, json_integer(11) );
  json_array_append( json_arr, json_integer(12) );
  json_array_append( json_arr, json_integer(14) );
  json_array_append( json_arr, json_integer(9) );

Finally I dump the JSON Object into a string format and output it to screen.

  s = json_dumps(root, 0);
  puts(s);

Last I have to free the JSON Object file.

  json_decref(root);

Remember to compile this with the -ljansson. For example:

gcc -o test test.c -ljansson


Running this will give the output:

{"destID": 1, "command": "enable", "respond": 0, "data": [11, 12, 14, 9]}


That's it for today. Now I should be able to generate strings to send from my RPi to Arduino, next up is for Arduino to parse and read the incoming JSON message.

15 comments :

  1. thanks.. it helps me lot

    ReplyDelete
  2. And what is the puts(something)? Belongs to string.h ?

    ReplyDelete
    Replies
    1. That writes the string out to stdout. That's how you get the output of the string.

      Delete
  3. Thanks a lot buddy, keep up the good work.

    ReplyDelete
  4. See http://jansson.readthedocs.io/en/2.8/apiref.html when using json_dumps.

    char *json_dumps(const json_t *json, size_t flags)
    Returns the JSON representation of json as a string, or NULL on error. flags is described above. The return value must be freed by the caller using free().

    free( s );

    ReplyDelete
  5. Neat and precise! Thanks for the post. Minor bug? : free(s) after puts(s)

    ReplyDelete
    Replies
    1. No need, json_decref(root); will take care of freeing...

      Delete
    2. I don't think so. Following the doc.

      char *json_dumps(const json_t *json, size_t flags)
      Returns the JSON representation of json as a string, or NULL on error. flags is described above. The return value must be freed by the caller using free().

      Delete
  6. This is a very useful example. Thanks for sharing!

    ReplyDelete
  7. I believe, `json_array_append_new()` should be used instead of `json_array_append()`, as the former would steal the object.

    ReplyDelete
    Replies
    1. I think you are right,thanks for mention that.

      Delete
  8. how can we create a json object form string?

    ReplyDelete
  9. I think you have a memory leak, you should use 'json_array_append_new'. Then also a free over s as someone already stated before

    ReplyDelete
  10. how to increase the heap size of the json object

    ReplyDelete