1

I have a c++ webassembly module with several function that is called wasmExec.wasm. So far i have been exporting methods from c++ to JavaScript that are located in the cpp file where the main() method is located using the EMSCRIPTEN_KEEPALIVE keyword. That is working just fine. I do see those methods when i do

wasm-nm wasmExec.wasm 

and i can call them from JavaScript and get the expected result. In order achieve clean methods name i have been disabling C++ name mangling.

Now i have tried to use EMSCRIPTEN_KEEPALIVE with static methods that are not located in the main.cpp file instead in a separate namespace and separate cpp and header files. In those classes i am also using EMSCRIPTEN_KEEPALIVE but unfortunately the produced wasm module is eliminating my method and thus i can not see them when executing wasm-nm wasmExec.wasm althout they are marked with EMSCRIPTEN_KEEPALIVE in the header as well as in the cpp file. i.e. here is an example

#ifndef API_REGISTRATION_REGISTRATIONMANAGER_H_
#define API_REGISTRATION_REGISTRATIONMANAGER_H_


#include <string>

#include <emscripten/emscripten.h>

using namespace std;

namespace api::registration {

#ifdef __cplusplus
extern "C" {
#endif


class RegistrationManager {
public:
    explicit RegistrationManager();
    virtual ~RegistrationManager();

    static char* EMSCRIPTEN_KEEPALIVE registerClient(
            char* userNameInputPtr, int userNameLength

    );

};


#ifdef __cplusplus
}
#endif


} 

#endif /* API_REGISTRATION_REGISTRATIONMANAGER_H_ */

I am using cmake to compile the project. In the target properties i have explicitly defined EXPORTED_FUNCTIONS to be equal to

set_target_properties(wasmExec PROPERTIES LINK_FLAGS "-std=c++17 -s WASM=1  -s TOTAL_MEMORY=512MB  -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1  -s VERBOSE=1  --pre-js /Projects/src/wasm/preModule.js -s DEMANGLE_SUPPORT=1 -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0  -s EXPORTED_FUNCTIONS='['registerClient']'    -s EXTRA_EXPORTED_RUNTIME_METHODS='['cwrap', 'getValue', 'setValue', 'registerClient' ]' " )

What could be the reason to not be able to register this the method "registerClient" within the webassembly module. I have even tired to use the option -s EXPORT_ALL=1 but that did not exported all the know methods as i was expcting it to do

I am compiling everything statically here i.e. below is the example of the registration_api cmake sub-folder

MESSAGE( STATUS "ADDING API_REGISTRATION_DIR")

set( API_REGISTRATION_SRC

    RegistrationManager.h RegistrationManager.cpp


    )
set(LIB_TYPE STATIC)

add_library(api_registration ${LIB_TYPE} ${API_REGISTRATION_SRC} )


target_include_directories(api_registration PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/")

the compilation process is successful with emscripten, nevertheless i do get this warrning exactly about the method i am trying to export:

em++: warning: undefined exported function: "registerClient" [-Wundefined]

if i put that method in the main.cpp it is automatically exported without any problem.

My question is what could be the reason why this export is not working when the method is located in external cp/hpp file?

Addition 15 May 2020: I was able to register the method only if i remove the class definition, change the namesapce to the one that main have. Then it seems that the underscore in the EXPORTED_FUNCTIONS is important i.e. -s EXPORTED_FUNCTIONS='['_registerClient']' . That worked for me. I was under the impression that if i use static methods that should work with classes as well, but it seems that not to be the case.

#ifndef API_REGISTRATION_REGISTRATIONMANAGER_H_
#define API_REGISTRATION_REGISTRATIONMANAGER_H_

#include <string>

#include <emscripten/emscripten.h>

using namespace std;

namespace wasm {

#ifdef __cplusplus
extern "C" {
#endif

char* EMSCRIPTEN_KEEPALIVE registerClient(
            char* userNameInputPtr, int userNameLength
    );

#ifdef __cplusplus
}
#endif

} 

#endif /* API_REGISTRATION_REGISTRATIONMANAGER_H_ */

thus my question has changed to: Can emscripten register a static method of a class with EMSCRIPTEN_KEEPALIVE or not?

Tito
  • 2,234
  • 6
  • 31
  • 65
  • "A C language linkage is ignored for the names of class members and the member function type of class member functions." https://stackoverflow.com/questions/1025345/extern-c-can-not-be-used-at-class-level – zakki May 21 '20 at 05:53
  • @zakki that's it , now i understand why. Many thanks for the response (and the answer) – Tito May 22 '20 at 07:32
  • EMSCRIPTEN_KEEPALIVE gave me a mangled function name in JS, how to have usual function name? – Dee Jan 27 '22 at 12:14

0 Answers0