C++ mangling name for use in Emscripten - c++

I'm trying to compile a simple HelloWorld Prgramm from C++ to Javascript using emscripten.
It works fine when I include a main function which call's e.g. the multi function.
Here is my code (HelloWorld.cpp).
#include <stdio.h>
class HelloWorld {
public: void sayHello() {
printf("Hello World Klasse! %f", multi(7));
}
public: double multi(double x){
return x * x;
}
};
However if I don't include a main function the emcc compile always put's out
ERROR root: No functions to process. Make sure you prevented LLVM
from eliminating them as dead (use EXPORTED_FUNCTIONS if necessary,
see the FAQ)
I know about the 'EXPORTED_FUNCTIONS' option which tells what functions should be included into the compile .js file.
I tried various diffrent things:
Using the mangling name, as far as I understood this the name should be '_multi_d10HelloWorldd'. I also tried without classname and some other combinations.
emcc -s HelloWorld.cpp -s EXPORTED_FUNCTIONS='["_multi_d10HelloWorldd"]'
Using the modifier EXPORT_ALL
emcc -s HelloWorld.cpp -s EXPORT_ALL=1
Whatever I do the functions won't be included in the final js file.
From what I understand from the EMCC FAQ I need to use EXPORTED_FUNCTIONS so I can later on call the desired function e.g. 'sayHello' from JS unsing the same method name.
And this is exactly what I need to do later on.
Could someone please point me to a solution or any other possible option which I may have not thought of ?
Is the mangling name I thought of correct ?

Create an "extern c" block. Inside this block define the functions you want to expose to javascript. These functions should be prefixed with an underscore. Inside one of these functions you can instantiate your C++ class.
This is the same approach as one would take when writing a dynamic library, which has the advantage that you can reuse your library in a native program should you wish.

Related

WebAssembly: Export namespace from C++ library to JavaScript

I'm trying to port the lhslib library (written in C++) to WebAssembly using emscripten (emcc v. 1.40.1, clang v. 12.0.0, macOS 10.15.5). Unfortunately I have a very limited understanding of C++, so please bear with me.
So far, I forked the repo, created a build folder, and from there started to try and convert the randomLHS.cpp file to WASM:
// a short overview of what the file looks like
#include "LHSCommonDefines.h"
#include "utilityLHS.h"
namespace lhslib
{
void randomLHS(int n, int k, bclib::matrix<int> & result, bclib::CRandom<double> & oRandom)
{
// further contents of the file
}
}
Running
emcc ../src/lhslib/randomLHS.cpp -I../src/bclib -o randomLHS.html
creates the expected files randomLHS.wasm ,randomLHS.js, and randomLHS.html.
However, when serving the html file and inspecting the Module object created by emscripten, it does not contain the desired randomLHS function.
I then read about the EXPORTED_FUNCTIONS option and proceeded to try the following
emcc ../src/lhslib/randomLHS.cpp -I../src/bclib -o randomLHS.html -s EXPORTED_FUNCTIONS='["_randomLHS"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
This results in the following error:
emcc: error: undefined exported function: "_randomLHS" [-Wundefined] [-Werror]
Unfortunately I couldn't find any examples showcasing how to export a namespace (as in the randomLHS file), or how to specify a function from the namespace that should be exported.
Could you guide me on how I could achieve this?
Thanks for you help!
So according to the emscripten docs on using ccall and cwrap:
These methods can be used with compiled C functions — name-mangled C++ functions won’t work.
I believe there are other ways to do this; check out WebIDL Binder and Embind.

How to turn off submodule of a C++ library based on preprocessor defined macro

What I'm doing I'm writing a C++ library with dependence on NetCDF library. For example,
include <netcdf>
class myLib {
public:
myLib();
myLib(const myLib&);
virtual ~myLib();
std::string probe_data(std::string & file_path);
...
And the function probe_data uses the functions from NetCDF library.
What is the problem I have defined a preprocessor macro CANALOGSIO_WITHOUT_NETCDF. Because in some system, there is no NetCDF library installed. So I would like to turn off this functionality in my library, for example, the library will still have probe_data function, but it simply returns NetCDF not installed.
What would be a good practice of doing that? Thank you!
I'll list 2 different methods which came to my mind for this.
1, just use ifdefs in the definition of the function. This will keep the uniform interface and everyone could call it.
class myLib {
...
std::string probe_data(std::string & file_path) {
#ifdef NETCDF
return do_real_probe(file_pat);
#else
cerr << "NOt implemented function" << endl;
return "";
#endif
}
...
This requires separate compilation for separate systems. YOu need to supply the definition of the macro at the compilation comand line, i.e. with gcc:
g++ -DNETCDF ..
the second method wold be based on the library approach. You can compile separate implementation libraries for different systems. Then at link time you can choose which static library to use (or at run time for dynamic libs). Most likely you would only deliver the library which work on the target system and nothing will. You might get away without #ifdefs if you choose so, just have different implementation in different files>
sys1.cpp
string probe(string &) { return do_probe();}
gcc sys1.cpp -o sys1.so -shared
sys2.cpp
string probe(string &) {cerr << messate; return "";}
gcc sys2.cpp -o sys2.so -shared
Now you just need to deliver the correct library (sys1 or sys2) to the correct system. Or a correct statically linked image of your program.
There are multiple way to use conditional compilation to do it. So you decide.

I receive different results on UNIX and WIN when use static members with static linking of shared library to executable. Please explain why?

Please consider following peace of code:
// 1. Single header file. Imagine that it is some static library.
// Counter.h
#pragma once
struct Counter
{
Counter()
{
++getCount();
}
static int& getCount()
{
static int counter = 0;
return counter;
}
};
// 2. Shared library (!) :
// main_DLL.cpp
#include <iostream>
#include "counter.h"
extern "C"
{
__declspec(dllexport) // for WIN
void main_DLL()
{
Counter c;
std::cout << "main_DLL : ptr = " << &Counter::getCount()<< " value = " << Counter::getCount() << std::endl;
}
}
// 3. Executable. Shared library statically (!) linked to the executable file.
// main.cpp
#include "counter.h"
#include <iostream>
extern "C"
{
__declspec(dllimport) // for WIN
void main_DLL();
}
int main()
{
main_DLL();
Counter c;
std::cout << "main_EXE : ptr = " << &Counter::getCount() << " value = " << Counter::getCount() << std::endl;
}
Results:
Results for WIN (Win8.1 gcc 5.1.0):
main_DLL : ptr = 0x68783030 value = 1
main_EXE : ptr = 0x403080 value = 1
// conclusion: two different counters
Results for UNIX (Red Hat <I don’t remember version exactly> gcc 4.8.3):
main_DLL : ptr = 0x75693214 value = 1
main_EXE : ptr = 0x75693214 value = 2
// conclusion: the same counter addressed
Building:
Building for WIN:
g++ -c -Wall -Werror -o main_DLL.o main_DLL.cpp
g++ -shared -Wl,--out-implib=libsharedLib.a -o libsharedLib.so main_DLL.o
g++ -Wall –Werror -o simpleExample main.cpp -L./ -lsharedLib
Building for UNIX:
g++ -c -Wall -Werror -fPIC -o main_DLL.o main_DLL.cpp
g++ -shared -fPIC -o libsharedLib.so main_DLL.o
g++ -Wall –Werror -fPIC -o simpleExample main.cpp -L./ -lsharedLib
So, you see that I added –fPIC on UNIX and there is no need to create import library for UNIX, because all exports symbols are included inside shared library. On Windows I use __declspec for it.
For me, results on Windows are pretty much expected. Because shared library and executable are building separately and they should know about static variable in Counter::getCount. They should simply allocate memory for it, that’s why they have different static counters.
I did quite some analysis using tools like nm, objdump. Although I’m not a big expert in them, so I haven’t found anything suspicious. I can provide their output if needed.
Using ldd tool I can see that library linked statically in both cases.
Why I can’t see the same results on Unix for me it’s strange. Could the root cause lie in building options (–fPIC, for example), or I’m missing something?
In windows, A DLL is not exporting global and static symbols unless you add the dllexport statement, therefore, the linker doesn't even know they exists, so it allocate new instance for the static member.
In linux/unix a shared lib is exporting all the global and static symbols, so when the linker find the existence of the static member in the shared lib, it just use its address.
That is the reason for the different result.
EDIT: This is a complete rewrite of the answer. With much more details.
I think that this question deserves more elaborated answer. Especially that there are things that were not mentioned so far.
Dependency Walker
Let me start with referring to the “Dependency Walker” program.
It is a nice program (although these days a bit old-schoolish in its look & feel) that allows analyzing Windows binaries (both EXE and DLL) for symbols that they export/import and their own dependencies to other DLLs. Also it allows showing undecorated symbol names but this seems to be working only with MSVC build binaries. (And some more but that is not important here.)
Thanks to this program crucial information (for this question) can be uncovered. So I encourage you to use it during experiments.
Exporting policy on Linux vs. Windows
SHR already pointed this out but I will mention it also for completeness of the answer. And some extra details.
On Linux every symbol gets exported from a shared library by default. On the other hand on Windows you have to explicitly state which symbols to export from a shared library.
GCC seems however to provide some means of controlling exports in "Windows style". See for example Visibility entry on GCC Wiki.
Also note that there are various ways of exporting on both Linux and Windows. For example both seem to support exporting selectively by providing linker with a list of names for symbols to export. But it also seems that nowadays (on Windows at least) this isn't really used much. __declspec approach seems to be preferred.
What can be exported?
After that general introduction let's now stick to Windows case. Nowadays you export/import symbols from shared libraries by using the __declspec. Just as shown in the question. (Well maybe not exactly that - typically you use a #define to handle bi-directionality as shown in already mentioned Visibility entry on GCC Wiki.)
But the declaration can be applied not only to functions, methods and global variables. It can also be applied to types. For example you can have:
class __declspec(dllexport) Counter { /* ... */ };
Such exporting/importing means in general that all members get exported/imported.
Not so easy!
But it would be too easy, wouldn't it? The complication is that GCC and MSVC handle exporting types differently.
My notes here are based mostly on experiments (checks done using Dependency Walker) so I can be wrong or not precise enough. But I did observe differences in behavior.
In tests I used MSVC 2013 from the Express Edition with update 5. For GCC I used MinGW distro from nuwen.net, version 13.0.
MSVC, when exporting entire type, exports each and every member. Including implicitly defined members (like compiler generated copy constructor). And including inlined functions. Furthermore if inlined function has some static local variables they get exported to (!).
GCC on the other hand seems to be far more restrictive. It doesn't export implicitly defined members. Nor it doesn't export inlined members.
Exporting/Importing inline functions
If instead of exporting entire type you would explicitly export an inlined function then and only then will GCC really export it. But still it will not export static local variables in that function.
Further more if you try to import an inlined function GCC will error. With GCC you cannot define symbols that you are importing. And this happens when you import inlined (and so defined) symbol. So in fact it doesn't make any sense to export inlined functions with GCC.
MSVC allows to import inlined functions. In all cases I checked it didn't seem to actually inline the function but instead called the imported version.
Yet note that because MSVC in case of inlined function exports also its static local variables it would be possible for it to really inline the function (rather than import it) while maintaining a single copy of static local variables. For ordinary programs such behavior is mandated by the Standard (N3337, C++11), in point 7.1.2 ([dcl.fct.spec]) at $4 we can read:
(…) A static local variable in an extern inline function always refers to the same object. (…)
But a program and a shared library are actually more like two programs so they are out of scope for the Standard. Yet MSVC even in that case acts (or better to say: could act) as one would expect from a single program.
Solution
Denis Bakhvalov in a comment provided solution for his own question. The solution is to move getCount function from header to source file and export/import it.
This seems to be the only solution portable between GCC and MSVC. Or to be more precise MSVC allows more solutions to this problem but none of them will work when program is build under GCC.
The variable trick
The above is not entirely true. There is another workaround that will work consistently between GCC and MSVC.
This is to stop using static local variable. Instead make it a global variable (most likely by making it static variable in the class) and export it. This will make the trick as well.
Sadly there is no way (or I don't know any) to directly force exporting/importing static local variables. You have to change them to global variables to do that.
MSVC solutions
With MSVC you have more options.
As mentioned before exporting/importing the inlined function itself (whether directly or through type) will do the job.
Summary
As described above even consistency between GCC and MSVC on Windows only requires care. You have to limit yourself to stay in common subset of allowed solutions.
Keeping the program (source) interoperable between Linux and Windows even if with same compiler (GCC) also requires care.
Luckily there is a common subset for all three environments: GCC on Linux, GCC on Windows and MSVC on Windows. That common subset is described already by mentioned Denis' comment.
So do not inline functions that you intend to export/import. Keep them in sources. And on Windows builds (regardless of compiler) export them explicitly (otherwise you will get linker error anyway since the functions in sources of a shared library will not be available when building program).
Note that this is actually a reasonable approach on its own. Inlining function from shared library doesn't seem wise. It freezes not only the interface but also implementation (of that function). You can no longer change this function freely (and deliver new version of your shared library) since all clients would have to be rebuild since they could have inlined that function. So it is a wise approach by itself not to inline from shared library. And as a bonus it assures that your sources are multi-platform friendly.
Also do have a look into the mentioned Visibility entry on GCC Wiki. It might be reasonable to use that approach (of explicit exports) on Linux as well since it seems cleaner (from design point of view) and more efficient at runtime. While it fits well what you have to do for Windows anyway.

libtool linkage - global state initalization of convenience libraries

I have a setup that does not work, and I have no idea what I am doing wrong here -
I am trying to convert a project from handcrafted Makefiles to autotools, and I think I have most of it set up correctly, as the application and all its convenience libraries builds and links correctly, but there is some trouble with the global state initializers of the convenience libraries.
Some of the libraries follow a pattern like this in the code:
// in global scope of somemodule.cpp
namespace {
bool registered = ModuleShare::registerModule<SomeModule>("SomeModule");
}
this code, along with the actual module source, is compiled into a convenience library using libtool
// libsomething Makefile.am
noinst_LTLIBRARIES = libsomething.la
libsomething_la_SOURCES = \
[ ... ]
moduleshare.cpp moduleshare.h \
somemodule.cpp somemodule.h \
[ ... ]
and this library is built, and referenced in the application Makefile.am as follows:
// someapp Makefile.am
bin_PROGRAMS = someapp
someapp_SOURCES = someapp.c someapp.h
someapp_CPPFLAGS = -I ${top_srcdir}/something
someapp_LDADD = ${top_srcdir}/something/libsomething.la
I have modified ModuleShare::registerModule to verify it is not called:
template<typename T>
static bool registerModule(const std::string &module){
printf("%s\n", module.c_str());
[ ... ]
return true;
}
What could be the reason for this?
EDIT:
At this point, I have figured out that this problem is related to the linker that is allowed to remove unused symbols during linkage. If I link manually using --whole-archive, everything works as expected.
Coming from a C background, I also tried
static void
__attribute__((constructor))
register (void)
{
ModuleShare::registerModule<SomeModule>("SomeModule");
}
but that also does not produce the behaviour that I expected, which is wierd, considering that I rely on this construct a lot in my private C projects.
At this point, I am open to suggestions in any direction. I know that libtool does not provide per-library flags in LDADD, and I can't, and simply don't want to compile everything with --whole-archive just to get rid of these symptoms. I have only limited control over the codebase, but I think what I really need to ask here is, what is a good and reliable way to initialize program state in a convenience library using autotools?
EDIT2:
I think I am a step closer - it seems that the application code has no calls to the convenience library, and hence the linker omits it. The application calls into the library only via a templated function defined in a header file of SomeModule, which relies on the static initializers called in the convenience libraries.
This dependency reversion is screwing over the whole build.
Still, I am unsure how to solve this :/
Thanks,
Andy
Since you're using autotools, you might be in a situation where exclusive use of gcc is feasible. In that case you can apply the `used' attribute to tell gcc to force the linker to include the symbol:
namespace {
__attribute__ ((used))
bool registered = ModuleShare::registerModule<SomeModule>("SomeModule");
}
Instead of using --whole-archive, have you tried to just add -u registered?
As ld manual states:
-u symbol
--undefined=symbol
Force symbol to be entered in the output file as an undefined symbol. Doing this may, for example, trigger linking of additional modules from standard libraries. -u may be repeated with different option arguments to
enter additional undefined symbols. This option is equivalent to the "EXTERN" linker script command.
Edit: I think that what you try to achieve is quite similar to Qt's plugin management. This article details it a bit. And this is 4.8's official documentation.
Taking into account that convenience libraries are statically build, maybe, it would be enough to create a dummy instance inside this convenience library (or a dummy use of registered) and declare it as extern where you use it (this is what Q_EXPORT_PLUGIN2 and Q_IMPORT_PLUGIN are doing).
This answer might require too many code changes for you, but I'll mention it. As I mentioned before, the convenience library model is a kind of static linkage where libraries are collated together before final linkage to an encapsulating library. Only in this case the "library" is an executable. So I'd imagine that stuff in the unnamed namespace (static variables essentially), especially unreferenced variables would be removed. With the above code, it worked as I kind of expected it to.
I was able to get registerModule to print it's message without special linker tricks in a convenience library like this:
somemodule.cpp
// in global scope
namespace registration {
bool somemodule = ModuleShare::registerModule<SomeModule>("SomeModule");
}
someapp.cpp
// somewhere
namespace registration {
extern bool somemodule;
... // and all the other registration bools
}
// in some code that does initialization, possibly
if (!(registration::somemodule && ...)) {
// consequences of initialization failure
}

Easiest to use, lightweight, platform independent graphing library for C++

What is the simplest to use c++ library that graphs functions like matlab and octave do? I have looked over several and have found similar major problems with all of them: i cannot compile an empty program that only has
#include <iostream>
#include "header_to_include.h"
int main(){
return 0;
}
i have found koolplot, some wxwidget stuff, sdl_graph, gnuplot++, and something with Qt. ive looked at some of the ones on the list here, but some are for other languages while others use installers or depended on other programs. When I got files extracted and tried compiling my simple code or given example code from within the download, codeblocks always complains about missing headers or variables or some other things.
i would use gnuplot, except i dont want to create gnuplot files from my cpp files, even if its through a pipe. i want to be able to graph straight from the program.
is there nothing that is simply a handful of files in a zip that can be extracted and used in moments rather than having to figure out which files to include, installing/downloading other major libraries, etc?
edit:
for example, i found http://sdl-grapher.googlecode.com/svn/trunk/ and downloaded the files. i already have sdl, so i copied sdlgraph.h into the includes folder and left a copy in the same directory as example.c. when i compile, i find that for some reason, #include <sdlgraph.h> doesnt work. also the int main() has no arguments despite being a SDL program. after fixing that up, i get undefined reference to 15 different functions that i can clearly see in the sdlgraph.h file such as init_graph and draw_grid
About your errors:
Since you're very new to C++ I'll explain your undefined reference errors.
In C++ you can declare a function like this:
void foo();
However, since it's declared, it doesn't main it's defined. Definitions can exist in C++ source file, libraries but also headers.
Defining the previous example:
void foo() {
std::cout << "void foo() has been called." << std::endl;
}
The error you get means that those functions just aren't defined.
I quess you have to link your application with the SDL libraries.
For more info see:
http://content.gpwiki.org/index.php/SDL:Tutorials:Setup
For more info about dynamic and static linking see:
http://www.learncpp.com/cpp-tutorial/a1-static-and-dynamic-libraries/
Hope it helps!