मुझे ओएसएक्स के तहत रूबी के लिए लिखी गई सी ++ लाइब्रेरी को निर्यात करने के लिए रूबी एक्सटेंशन बनाने में समस्याएं हैं I यह सरल उदाहरण: एक bad_cast अपवाद मेंसी ++ रूबी एक्सटेंशन बनाने में असमर्थ
#include <boost/regex.hpp>
extern "C" void Init_bayeux()
{
boost::regex expression("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
}
परिणाम फेंके:
#0 0x00000001014663bd in __cxa_throw()
#1 0x00000001014cf6b2 in __cxa_bad_cast()
#2 0x00000001014986f9 in std::use_facet<std::collate<char> >()
#3 0x0000000101135a4f in boost::re_detail::cpp_regex_traits_base<char>::imbue (this=0x7fff5fbfe4d0, [email protected]) at cpp_regex_traits.hpp:218
#4 0x0000000101138d42 in cpp_regex_traits_base (this=0x7fff5fbfe4d0, [email protected]) at cpp_regex_traits.hpp:173
#5 0x000000010113eda6 in boost::re_detail::create_cpp_regex_traits<char> ([email protected]) at cpp_regex_traits.hpp:859
#6 0x0000000101149bee in cpp_regex_traits (this=0x101600200) at cpp_regex_traits.hpp:880
#7 0x0000000101142758 in regex_traits (this=0x101600200) at regex_traits.hpp:75
#8 0x000000010113d68c in regex_traits_wrapper (this=0x101600200) at regex_traits.hpp:169
#9 0x000000010113bae1 in regex_data (this=0x101600060) at basic_regex.hpp:166
#10 0x000000010113981e in basic_regex_implementation (this=0x101600060) at basic_regex.hpp:202
#11 0x0000000101136e1a in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign (this=0x7fff5fbfe710, p1=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", p2=0x100540b19 "", f=0) at basic_regex.hpp:652
#12 0x0000000100540a66 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign (this=0x7fff5fbfe710, p1=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", p2=0x100540b19 "", f=0) at basic_regex.hpp:379
#13 0x0000000100540a13 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign (this=0x7fff5fbfe710, p=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", f=0) at basic_regex.hpp:364
#14 0x000000010054096e in basic_regex (this=0x7fff5fbfe710, p=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", f=0) at basic_regex.hpp:333
#15 0x00000001005407e2 in Init_bayeux() at bayeux.cpp:10
#16 0x0000000100004593 in dln_load (file=0x1008bc000 "/Users/todi/sioux/lib/debug/rack/bayeux.bundle") at dln.c:1293
मैं के साथ विस्तार संकलन:
g++ ./source/rack/bayeux.cpp -o /Users/todi/sioux/obj/debug/rack/bayeux.o -Wall -pedantic -Wno-parentheses -Wno-sign-compare -fno-common -c -pipe -I/Users/todi/sioux/source -ggdb -O0
और अंत के साथ गतिशील पुस्तकालय लिंक:
g++ -o /Users/todi/sioux/lib/debug/rack/bayeux.bundle -bundle -ggdb /Users/todi/sioux/obj/debug/rack/bayeux.o -L/Users/todi/sioux/lib/debug -lrack -lboost_regex-mt-d -lruby
मेरे पास है वेब पर कान लगाया और सभी प्रकार के लिंक और कंपाइलर स्विच की कोशिश की। अगर मैं निष्पादन योग्य बनाता हूं तो ऐसी कोई समस्या नहीं है। क्या किसी और को ऐसी समस्या थी और समाधान मिला?
मैं आगे इस जांच की और पाया समारोह अपवाद के कारण इस तरह दिखता है कि है:
use_facet(const locale& __loc)
{
const size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
__throw_bad_cast();
#ifdef __GXX_RTTI
return dynamic_cast<const _Facet&>(*__facets[__i]);
#else
return static_cast<const _Facet&>(*__facets[__i]);
#endif
}
:
std::locale loc = std::locale("C");
std::use_facet< std::collate<char> >(loc);
एसटीडी का स्रोत :: मुक़ाबला < में> मैं फेंक बयान पाया
क्या इससे आपको कोई समझ आती है?
अद्यतन:
Todis-MacBook-Pro:rack todi$ g++ -shared -fpic -o bayeux.bundle bayeux.cpp
Todis-MacBook-Pro:rack todi$ ruby -I. -rbayeux -e 'puts :ok'
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abort trap
संस्करणों:: मैं जनवरी के सुझाव की कोशिश की है
Todis-MacBook-Pro:rack todi$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]
Todis-MacBook-Pro:rack todi$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin10/4.5.2/lto-wrapper
Target: x86_64-apple-darwin10
Configured with: ../gcc-4.5.2/configure --prefix=/opt/local --build=x86_64-apple-darwin10 --enable-languages=c,c++,objc,obj-c++,fortran,java --libdir=/opt/local/lib/gcc45 --includedir=/opt/local/include/gcc45 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-4.5 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-4.5 --with-gxx-include-dir=/opt/local/include/gcc45/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --enable-stage1-checking --disable-multilib --enable-fully-dynamic-string
Thread model: posix
gcc version 4.5.2 (GCC)
अद्यतन:
यह नहीं use_facet() कि फेंकता में बंधे की जांच, लेकिन अगली पंक्ति, वास्तव में एक गतिशील कलाकार करता है। यह उदाहरण आरटीटीआई के साथ कुछ हो सकता है:
#define private public
#include <locale>
#include <iostream>
#include <typeinfo>
extern "C" void Init_bayeux()
{
std::locale loc = std::locale("C");
printf("size: %i\n", loc._M_impl->_M_facets_size);
printf("id: %i\n", std::collate<char>::id._M_id());
const std::locale::facet& fac = *loc._M_impl->_M_facets[ std::collate<char>::id._M_id() ];
printf("name: %s\n", typeid(fac).name());
printf("name: %s\n", typeid(std::collate<char>).name());
const std::type_info& a = typeid(fac);
const std::type_info& b = typeid(std::collate<char>);
printf("equal: %i\n", !a.before(b) && !b.before(a));
dynamic_cast< const std::collate<char>& >(fac);
}
मैंने printf() का उपयोग किया है क्योंकि cout का उपयोग भी विफल रहता है। ऊपर दिए गए कोड का उत्पादन होता है:
size: 28
id: 5
name: St7collateIcE
name: St7collateIcE
equal: 1
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abort trap
साथ गठन:
g++ -shared -fpic -o bayeux.bundle bayeux.cpp && ruby -I. -rbayeux -e 'puts :ok'
अद्यतन:
अगर मैं) मुख्य (करने के लिए Init_bayeux नाम बदलने और एक निष्पादन से लिंक, उत्पादन होता है वही, लेकिन समाप्त करने के लिए कोई कॉल नहीं है।
अद्यतन:
जब मैं साझा लाइब्रेरी लोड करने के लिए और Init_bayeux() निष्पादित करने के लिए एक छोटे से प्रोग्राम लिखने, फिर से, कोई अपवाद नहीं फेंक दिया जाता है:
#include <dlfcn.h>
int main()
{
void* handle = dlopen("bayeux.bundle", RTLD_LAZY|RTLD_GLOBAL);
void(*f)(void) = (void(*)(void)) dlsym(handle, "Init_bayeux") ;
f();
}
तो यह मेरे लिए लग रहा है, यह है कि ruby.exe कैसे बनाया गया था के साथ एक समस्या हो सकती है। क्या इसका कोई मतलब है?
अद्यतन: मैंने दो टाइप_इनो ऑब्जेक्ट्स के नाम वाले पते पर एक नज़र डाली थी। वही सामग्री, लेकिन अलग-अलग पते।मैंने लिंक कमांड में -flat_namespace स्विच जोड़ा। अब गतिशील_कास्ट काम करता है। बूस्ट रेगेक्स लाइब्रेरी के साथ मूल समस्या अभी भी मौजूद है, लेकिन मुझे लगता है कि यह साझा लाइब्रेरी में स्थिर रूप से बढ़ावा देने या -flat_namespace स्विच के साथ बूस्ट लाइब्रेरी का पुनर्निर्माण करके हल करने योग्य हो सकता है।
अद्यतन: अब मैं वापस बढ़ावा regex अभिव्यक्ति के साथ पहले ही उदाहरण के लिए कर रहा हूँ, इस आदेश के साथ निर्माण:
g++ -shared -flat_namespace -fPIC -o bayeux.bundle /Users/todi/boost_1_49_0/stage/lib/libboost_regex.a bayeux.cpp
लेकिन जब रूबी दुभाषिया में विस्तार लोड हो रहा है, स्थिर प्रतीकों में से आरंभ विफल रहता है :
ruby(59384,0x7fff712b8cc0) malloc: *** error for object 0x7fff70b19500: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Program received signal SIGABRT, Aborted.
0x00007fff8a6ab0b6 in __kill()
(gdb) bt
#0 0x00007fff8a6ab0b6 in __kill()
#1 0x00007fff8a74b9f6 in abort()
#2 0x00007fff8a663195 in free()
#3 0x0000000100541023 in boost::re_detail::cpp_regex_traits_char_layer<char>::init (this=0x10060be50) at basic_string.h:237
#4 0x0000000100543904 in boost::object_cache<boost::re_detail::cpp_regex_traits_base<char>, boost::re_detail::cpp_regex_traits_implementation<char> >::do_get ([email protected]) at cpp_regex_traits.hpp:366
#5 0x000000010056005b in create_cpp_regex_traits<char> (l=<value temporarily unavailable, due to optimizations>) at pending/object_cache.hpp:69
#6 0x0000000100544c33 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign (this=0x7fff5fbfe090, p1=0x100567158 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", p2=0x100567191 "", f=0) at cpp_regex_traits.hpp:880
#7 0x0000000100566280 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign()
#8 0x000000010056622d in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign()
#9 0x0000000100566188 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::basic_regex()
#10 0x0000000100566025 in Init_bayeux()
#11 0x0000000100003a23 in dln_load (file=0x10201a000 "/Users/todi/sioux/source/rack/bayeux.bundle") at dln.c:1293
#12 0x000000010016569d in vm_pop_frame [inlined]() at /Users/todi/.rvm/src/ruby-1.9.2-p320/vm_insnhelper.c:1465
#13 0x000000010016569d in rb_vm_call_cfunc (recv=4303980440, func=0x100042520 <load_ext>, arg=4303803000, blockptr=0x1, filename=<value temporarily unavailable, due to optimizations>, filepath=<value temporarily unavailable, due to optimizations>) at vm.c:1467
#14 0x0000000100043382 in rb_require_safe (fname=4303904640, safe=0) at load.c:602
#15 0x000000010017cbf3 in vm_call_cfunc [inlined]() at /Users/todi/.rvm/src/ruby-1.9.2-p320/vm_insnhelper.c:402
#16 0x000000010017cbf3 in vm_call_method (th=0x1003016b0, cfp=0x1004ffef8, num=1, blockptr=0x1, flag=8, id=<value temporarily unavailable, due to optimizations>, me=0x10182cfa0, recv=4303980440) at vm_insnhelper.c:528
...
फिर से, यह विफल नहीं होता है, जब मैं ऊपर से छोटे सी प्रोग्राम द्वारा साझा लाइब्रेरी लोड करता हूं।
अद्यतन:
g++ -shared -fPIC -flat_namespace -nodefaultlibs -o bayeux.bundle -static -lstdc++ -lpthread -lgcc_eh -lboost_regex-mt bayeux.cpp
वही त्रुटि के साथ
: अब मैं पहला उदाहरण स्थिर लिंक
ruby(15197,0x7fff708aecc0) malloc: *** error for object 0x7fff7027e500: pointer being freed was not allocated
एल otool पुष्टि की है कि हर पुस्तकालय स्थिर जुड़ा हुआ है:
bayeux.bundle:
bayeux.bundle (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
डीबग:
यदि मैं बूस्ट डीबग संस्करण के खिलाफ लिंक करता हूं, तो यह अपेक्षा की तरह काम करता है।
मैं व्यवहार आप वर्णित पुन: पेश नहीं कर सकते हैं संबंध है। मैंने उदाहरण सी ++ फ़ाइल को 'g ++ -shared -fpic -o bayeux.so -lboost_regex bayeux.cpp' और' रूबी-आई 'के साथ संकलित किया। -rbayeux -e 'रखता है: ठीक है' बिना किसी मुद्दे के एक्सटेंशन को लोड किया। हालांकि, जब मैंने '-lboost_regex' छोड़ा तो मुझे कुछ समस्याएं थीं। इसके अलावा, क्या आप निर्दिष्ट कर सकते हैं कि रूबी और बूस्ट के कौन से संस्करण आप उपयोग कर रहे हैं और हम इस समस्या को पुन: पेश कैसे कर सकते हैं? – Jan
@ जेन, कोशिश करने के लिए धन्यवाद। ओएस एक्स पर, मुझे 'इतना' एक्सटेंशन 'बंडल' में बदलना होगा (अन्यथा आवश्यकताएं लाइब्रेरी नहीं मिलेंगी) लेकिन नतीजा अभी भी वही है। –
@ जेन, आप बूस्ट लाइब्रेरी को छोड़ सकते हैं, यह इसके बिना विफल रहता है। यह उपयोग करने के लिए कॉल है _facet <> जो विफल रहता है। –