“在库中找不到函数符号” - JS-Ctypes [英] "Couldn't find function symbol in library" - JS-Ctypes
问题描述
int RFD_startBackgroundThread()
overlay.js
中的代码是 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);
代码在最后一行引发异常。它说在库中找不到函数符号
。
库是一个fat dylib二进制文件在OS X Lion(10.7)上结合了i386和x86_64(但不包括PPC拱门)。 Firefox版本11。
非常需要帮助。
谢谢。
Rahul。
在大多数Unix平台上,包括OS X,C函数都被映射为符号,一个下划线,所以 int foo(int)
最后只是 _foo
。
但是这对C ++来说是行不通的,因为在C ++中,可以用不同的方法来拥有两个不同的名字相同的函数,你可以使用 int foo(int )
和 double foo(double)
或 int MyClass :: foo(int)
,或 int foo< int>(int)
,依此类推。所以,C ++函数必须是 mangled 来给出一个唯一的字符串。 (然后,这个唯一的字符串被视为一个C函数 - 也就是前缀为_。)
jsctypes知道关闭_,但它不知道如何打乱你的功能,因为你只是给它一个名字,而不是一个完整的原型。所以,你必须找出其他方式,你的函数mangled的名称是 _Z25RFD_startBackgroundThreadv
。
没有可移植的标准如何名称被打乱。但是,Apple使用的C ++ ABI基于 Itanium C ++ API < a>,这需要一个API来修改和去除C ++函数。 Xcode附带了一个名为c ++ filt的工具,它封装了在命令行中使用的API,但是它只能处理解除绑定,而不是绑定。所以,它可以告诉你: 获取损坏名称的一种方法是从 另一种方法是自动化。像这样: ...将打印所有符号的demangled名称。 但是最好的办法是创建一个很小的.cpp文件,一个原型,编译它,然后用otool -SV tiny.a来查看这个名字。 你可以调用C ++函数。 但是这并不意味着你可以把它称为C函数。对于一个非常明显的例子,如果你想调用(非静态的)Foo :: bar(int),你最好有一个有效的东西作为this指针传递,并知道如何传递它。请参阅 https://bugzilla.mozilla.org/show_bug.cgi?id=505907详细了解Mozilla中的jsctypes不能做什么,以及为什么。 My C++ Library function is The code throws an exception on the last line. It says " 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 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 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 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 One way to get the mangled name is to start with 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. 这篇关于“在库中找不到函数符号” - JS-Ctypes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! _Z25RFD_startBackgroundThreadv
意味着 RFD_startBackgroundThread()
,但是它不能反其道而行之。
nm libfoo.dylib
开始,然后使用c ++ filt检查那些看起来不错的候选人,直到找到与你正在寻找的原型相匹配的人。
nm libfoo.dylib | awk'NF == 2 {printf%s,$ 1; system(c ++ filt$ 2)} NF!= 2 {print $ 0}'
int RFD_startBackgroundThread()
My code in the overlay.js
isuri = 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);
Couldn't find function symbol in library
".int foo(int)
ends up as just _foo
.int foo(int)
and double foo(double)
, or int MyClass::foo(int)
, or int 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 "_".)_Z25RFD_startBackgroundThreadv
._Z25RFD_startBackgroundThreadv
means RFD_startBackgroundThread()
, but it can't get the other way around.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. nm libfoo.dylib | awk 'NF==2 {printf "%s ",$1; system("c++filt " $2)} NF!=2{print $0}'