My C++ Library function is int RFD_startBackgroundThread()
My code in the overlay.js is
uri = addon.getResourceURI("components/mac/libReverbFirefoxExtensionLib.dylib");
this.extensionLib = ctypes.open(uri.path);
this.startBackgroundThread = this.extensionLib.declare("RFD_startBackgroundThread", ctypes.default_abi, ctypes.unsigned_int);
The code throws an exception on the last line. It says “Couldn't find function symbol in library“.
The library is a “fat dylib binary” combining both i386 and x86_64 (but not PPC arch) on OS X Lion (10.7). Firefox version 11.
Desperately need help.
Thanks.
Rahul.
In most Unix platforms, including OS X, C functions are mapped to symbols just by prefixing with an underscore, so
int foo(int)ends up as just_foo.But that doesn’t work for C++, because in C++, you can have two different functions with the same name, in a variety of different ways—you can have
int foo(int)anddouble foo(double), orint MyClass::foo(int), orint foo<int>(int), and so on. So, C++ functions have to be “mangled” to give a unique string. (And then, that unique string is treated like a C function—that is, prefixed with an “_”.)jsctypes knows about knocking off the _, but it can’t know how to mangle your function, because you’re just giving it a name, not a full prototype. So, you have to figure out in some other way that the mangled name of your function is
_Z25RFD_startBackgroundThreadv.There’s no portable standard for how names get mangled. However, the C++ ABI that Apple uses is based on the Itanium C++ API, which requires an API to mangle and demangle C++ functions. Xcode comes with a tool called c++filt that wraps up that API for use at the command line—but it only handles demangling, not mangling. So, it can tell you that
_Z25RFD_startBackgroundThreadvmeansRFD_startBackgroundThread(), but it can’t get the other way around.One way to get the mangled name is to start with
nm libfoo.dylib, then use c++filt to check the ones that look like good candidates, until you find one that matches the prototype you’re looking for.Another way is to automate that. Something like this:
… will print the demangled names of all of your symbols.
But probably the best way to go about it is to create a tiny .cpp file that has nothing in it but that one prototype, compile it, and use “otool -SV tiny.a” to see the mangled name.
So, it’s not that hard to get the name of the symbol for the C++ function you want to call.
But that doesn’t mean you can just call it as if it were a C function. For one pretty obvious example, if you want to call (non-static) Foo::bar(int), you’d better have a valid thing to pass as a “this” pointer, and know how to pass it. See https://bugzilla.mozilla.org/show_bug.cgi?id=505907 for details on what jsctypes in Mozilla can’t do, and why.