{"id":1554,"date":"2014-11-29T00:48:57","date_gmt":"2014-11-29T00:48:57","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=1554"},"modified":"2014-11-29T03:22:32","modified_gmt":"2014-11-29T03:22:32","slug":"calling-c-javascript-emscripten-minimal-example","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2014\/11\/calling-c-javascript-emscripten-minimal-example\/","title":{"rendered":"Calling C from JS with Emscripten, minimal examples"},"content":{"rendered":"<p>There are a few ways of doing this, this is the simplest, but also slowest. The options are listed on the Emscripten wiki <a href=\"http:\/\/kripken.github.io\/emscripten-site\/docs\/porting\/connecting_cpp_and_javascript\/Interacting-with-code.html\">here<\/a>.<\/p>\n<h2>Return an int, complete example<\/h2>\n<p>Sample C file (I called it call.c):<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;math.h&gt;\r\n\r\nint test1(int x) {\r\n  return sqrt(x);\r\n}\r\n\r\nint test2(int x) {\r\n  return sqrt(x)+1;\r\n}\r\n<\/pre>\n<p>Compile as follows:<\/p>\n<pre>\r\nemcc call.c -o call.js -s EXPORTED_FUNCTIONS=\"['_test1','_test2']\"\r\n<\/pre>\n<p>You can then create a html file which calls this JS code:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&lt;body&gt;\r\n&lt;script src=&quot;call.js&quot;&gt;&lt;\/script&gt;\r\n\r\n&lt;script&gt;\r\nvar result = Module.ccall(\r\n'test1', \/\/ name of C function\r\n'number', \/\/ return type\r\n&#x5B;'number'], \/\/ argument types\r\n&#x5B;28]); \/\/ arguments\r\n\r\ndocument.write(result);\r\n&lt;\/script&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<h2>Passing and returning an array of ints<\/h2>\n<p>This is a little harder, Emscripten doesn&#8217;t really help you out, you have to format the arrays in memory manually.<\/p>\n<p>Sample C program two functions, one passing and returning a char *, the other int *s.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;math.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\nchar *test1(char *instr) {\r\n\r\n  char *array = malloc(sizeof(char)*strlen(instr));\r\n  strcpy(array,instr);        \/\/ the horror!!\r\n  int size = strlen(array);\r\n  for(int n=0;n&lt;size;n++) {\r\n    if((array&#x5B;n] &gt;= 'a') &amp;&amp; (array&#x5B;n] &lt;= 'z')) array&#x5B;n] -= 'a'-'A';\r\n  }\r\n\r\n  return array;\r\n}\r\n\r\nint *test2(int *in,int size) {\r\n\r\n  int *array = malloc(sizeof(int)*size);\r\n\r\n  for(int n=0;n&lt;size;n++) {\r\n    array&#x5B;n] = in&#x5B;n]*2;\r\n  }\r\n\r\n  return array;\r\n}\r\n<\/pre>\n<pre>\r\nemcc call.c -o call.js -s EXPORTED_FUNCTIONS=\"['_test1','_test2']\"\r\n<\/pre>\n<p>The JS can then be called from html as follows:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n &lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&lt;body&gt;\r\n&lt;script src=&quot;call.js&quot;&gt;&lt;\/script&gt;\r\n\r\n&lt;script&gt;\r\n\r\nfunction write_1d_int32_array(ptr,array) {\r\n\r\n  for(i=0;i&lt;array.length;i++) {\r\n    Module.setValue(ptr,array&#x5B;i],'i32');\r\n    ptr += 4;\r\n  }\r\n\r\n}\r\n\r\nfunction read_1d_int32_array(ptr,length) {\r\n\r\n  var array = &#x5B;];\r\n\r\n  for(i=0;i&lt;length;i++) {\r\n    var value = Module.getValue(ptr+(i*4),'i32');\r\n    array.push(value);\r\n  }\r\n\r\n  return array;\r\n}\r\n\r\n\/\/ test1 - a C function that takes, and returns a C style string (char *)\r\n\r\nvar mystring = &quot;test&quot;;\r\nvar strptr = Module._malloc(mystring.length);\r\nModule.writeAsciiToMemory(mystring, strptr);\r\n\r\nvar retstrptr = Module.ccall('test1', \/\/ name of C function\r\n  'number', \/\/ return type\r\n  &#x5B;'number'], \/\/ argument types\r\n  &#x5B;strptr]); \/\/ arguments\r\n\r\n\/\/ Convert the resulting string to a JS string\r\nvar retstr = Pointer_stringify(retstrptr);\r\ndocument.write(retstr);\r\n\r\n\/\/ test2 - a C function that takes, and returns a C style int array (int *)\r\n\r\nvar myarray = &#x5B;10,20,30,40,50];\r\nvar arrayptr = Module._malloc(myarray.length*4);\r\nwrite_1d_int32_array(arrayptr,myarray);\r\n\r\nvar retarrayptr = Module.ccall('test2', \/\/ name of C function\r\n  'number', \/\/ return type\r\n  &#x5B;'number'], \/\/ argument types\r\n  &#x5B;arrayptr,myarray.length]); \/\/ arguments\r\n\r\n\/\/ Convert the resulting pointer to a JS array\r\nvar retarray = read_1d_int32_array(retarrayptr,myarray.length);\r\ndocument.write(retarray);\r\n\r\n&lt;\/script&gt;\r\n\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>There are a few ways of doing this, this is the simplest, but also slowest. The options are listed on the Emscripten wiki here. Return an int, complete example Sample C file (I called it call.c): #include &lt;math.h&gt; int test1(int x) { return sqrt(x); } int test2(int x) { return sqrt(x)+1; } Compile as follows: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-1554","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-p4","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=1554"}],"version-history":[{"count":9,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1554\/revisions"}],"predecessor-version":[{"id":1556,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1554\/revisions\/1556"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=1554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=1554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=1554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}