13

I would like to use C source code in an easy way with JavaScript (using only free/libre software). So Emscripten seems to be a good option. https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html

There is an example to export one function:

emcc tests/hello_function.cpp -o function.html -s EXPORTED_FUNCTIONS="['_int_sqrt']"

But there are many functions that would be relevant to use in JavaScript. Moreover, it seems that I will have to add some more for accessing members of structures. Accessing struct fields from emscripten

So, I am wondering if it is possible to export all functions (except the ones of libc) without creating a big array with all the names, even if it could be a JS size issue and efficiency issue.

Regards.

  • The challenge with automating this process for all functions in a file is if you are using any types that are not supported natively by Emscripten. As long as you stick to built-in types, though, it should be straight-forward (and I'm sure someone has already built a script to do it.) – Charles Ofria Oct 18 '15 at 01:00

3 Answers3

10

A way to export all functions is to use both the -s LINKABLE=1 https://github.com/kripken/emscripten/blob/1.34.12/src/settings.js#L461 and -s EXPORT_ALL=1 https://github.com/kripken/emscripten/blob/1.34.12/src/settings.js#L385 options when compiling.

emcc tests/hello_function.cpp -o function.html -s LINKABLE=1 -s EXPORT_ALL=1

Just having -s EXPORT_ALL=1 does work, but on my system results in the following warnings:

warning: unresolved symbol: remquof
warning: unresolved symbol: ilogb
warning: unresolved symbol: nextafter
warning: unresolved symbol: remquo
warning: unresolved symbol: fesetround
warning: unresolved symbol: llvm_fma_f64

However, this doesn't give you exactly what you want, since libc functions would be exported as well. For example, you could call

Module.ccall('printf', 'number', ['string'], ['Passing a string from Javascript to C\n');

just fine, and it would send the string to the standard output (which by default is just the browser console).


This answer is based on @zakki's answer.

Community
  • 1
  • 1
Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
6

Only a partial answer. To avoid maintaining an array of functions, you can use the EMSCRIPTEN_KEEPALIVE macro when you define a function

void EMSCRIPTEN_KEEPALIVE my_function()
{
  printf("I am being kept alive\n");
}

You can see this in the docs at https://kripken.github.io/emscripten-site/docs/api_reference/emscripten.h.html#c.EMSCRIPTEN_KEEPALIVE

Admittedly this does not export all functions, just the ones marked with EMSCRIPTEN_KEEPALIVE.

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
  • 4
    This requires annotating the existing source code, which can be difficult for a large third party library. – CMCDragonkai Sep 02 '17 at 07:11
  • this should be the answer, imagine exporting all C libs, C++ libs functions out to js, that's disaster – Dee Jan 27 '22 at 11:37
1

Use -s EXPORT_ALL=1.

If true, we export all the symbols. Note that this does not affect LLVM, so it can still eliminate functions as dead. This just exports them on the Module object.

https://github.com/kripken/emscripten/blob/master/src/settings.js#L300

zakki
  • 2,283
  • 14
  • 20