在XCode 4.5中使用ZXing库时,架构armv7的未定义符号
我正在尝试做什么
在我的iPhone项目中集成Zxing ,QR码阅读器框架。 我从这里检查了ZXing sdk。 我运行了名为ScanTest的ZXing示例项目,没有任何问题。 但是,当我尝试将图书馆与我的项目集成时,我收到了错误。
项目规范
- 目标操作系统 :iOS 6.0
- 部署目标 :iOS 5.0或更高版本。
- testing :iPhone 4和iPhone 3GS。
- XCode :Xcode 4.5.1
- ZXing版本 :2.0
问题
当我在ZXing自述文件中进行每一个整合步骤之后,我正在得到像这样的构build错误
Undefined symbols for architecture armv7: "std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from: zxing::qrcode::Detector::computeDimension(zxing::Ref<zxing::ResultPoint>, zxing::Ref<zxing::ResultPoint>, zxing::Ref<zxing::ResultPoint>, float) in libZXingWidget.a(Detector-B8B28E953F840D47.o) Undefined symbols for architecture armv7: "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)", referenced from: zxing::Exception::Exception(char const*) in libZXingWidget.a(Exception.o) zxing::common::StringUtils::guessEncoding(unsigned char*, int, std::map<unsigned int, std::string, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::string> > >
有27个这样的错误..我只复制了前两个。
我发现了什么
那么,我通过这个 , 这个 , 这个 , 这个 , 这个 , 这个 , 这个线程在stackoverflow中,都带有相同的错误信息。 没有解决scheme为我工作。
然后我在ZXing论坛上发现了这个closures的线程 ,讨论了同样的问题。 从这个讨论,一些可能的解决scheme(为一些工作)
第一个错误是(可能),因为你没有将main.m重命名为main.mm。 第二个错误是(可能),因为你没有链接到部件库
我也重新命名了我的main.m,交叉检查我是否已经添加了这个库才发现我确实有。 所以情况并非如此。
将库的架构更改为“标准(armv7,armv7s)”以匹配我的主项目后,我便能够成功编译该应用程序。
我的项目,目标,库项目(用于debugging,分发,发布)体系结构是作为Standard (armv7, armv7s)
。 所以也没有运气。
然后他们closures了这个问题,
zxing项目已经更新,以添加armv7s拱门和删除armv6拱门。 这些改变需要(1)为iPhone 5构build,这是armv7s和(2)构build,因为Xcode 4.5不包括对armv6的支持。 如果您有自己的项目文件,则需要自行进行这些更改。 这些是不是特定于zxing的一般变化,所以如果您遇到麻烦,您可以在一般论坛(如StackOverflow)中获得更多/更快的帮助。
所以在这里,我在StackOverflow。
还有一点
在ZXing整合的README文件中 ,整合的第一步是,
1)在“
zxing/iphone/ZXingWidget/
”下find“ZXingWidget.xcodeproj”文件。 拖动ZXingWidget.xcodeproj并将其放到Xcode项目的“组和文件”边栏的根目录下。 将出现一个对话框 – 确保“复制项目”未选中,“参考types”是“相对于项目”,然后单击“添加”。 或者,您可以右键单击项目导航器,然后select“将文件添加到”MyProject“”。
当我将ZXingWidget.xcodeproj文件拖到我的项目中时,没有对话框。 该项目直接添加到项目中,我无法设置“复制项目”和“引用types”属性。 我不知道这是一个xcode 4.5的新function或一个错误。 这是我无法正确按照自述文件进行的唯一步骤。
那么,你有我拥有的所有信息。 我试图解决这个问题6个小时。 任何想法?
那么,我终于得到了它的工作..对于谁在未来遇到这个..
-
将main.m文件重命名为main.mm.
ZXing的自述文件说明了为什么我们需要这个
可能会发生这样的情况,当试图用ZXingWidgetController构build自己的项目时,会出现像“undefined reference to”这样的链接器错误。 如果这个错误看起来像一个c ++未定义的引用,那么将main.m重命名为main.mm(Objective-C ++源代码后缀)可能会解决问题
-
重命名使用ZXing libray函数的文件(ViewController / View),使其扩展名为.mm。
-
检查整个项目的架构设置。 在您的项目设置,目标设置和ZXing项目(您添加到主项目中)和目标设置中,将体系结构和有效体系结构作为armv7 armv7s 。
-
在主项目 – > 构build设置中,滚动并查找选项, C ++语言方言和C ++标准库 。 为他们两个select选项“编译器默认” 。 (这是我错过的步骤,因为最新的XCode模板具有不同于旧版本的编译器默认设置,所以需要这一步。
-
您还可能必须将ZXingWidget的“ 仅生成有效架构 ”标志设置为
NO
。 就我而言,这个字段已经是NO
这些解决了我的问题..
更新
Google于2013年12月退休ZXing iOS / Objective C端口。 所以iOS的Zxing项目不再维护和更新为新的iOS版本。 另外Zxing不支持Arm64架构,这是根据新XCode版本的标准架构之一。
所以鼓励开发人员转移到本地Apple框架来阅读从iOS7开始提供的条形码 。 看到这个一步一步的教程。
我已经按照上面的所有build议,而且一切正常编译,链接失败:
"std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from: zxing::qrcode::Detector::computeDimension(zxing::Ref<zxing::ResultPoint>, zxing::Ref<zxing::ResultPoint>, zxing::Ref<zxing::ResultPoint>, float) in libZXingWidget.a(Detector-B8B28E953F840D47.o) zxing::GridSampler::checkAndNudgePoints(zxing::Ref<zxing::BitMatrix>, std::vector<float, std::allocator<float> >&) in libZXingWidget.a(GridSampler.o) zxing::qrcode::DecodedBitStreamParser::decodeNumericSegment(zxing::Ref<zxing::BitSource>, std::string&, int) in libZXingWidget.a(DecodedBitStreamParser-64E27B33E79CBC52.o) zxing::qrcode::Mode::forBits(int) in libZXingWidget.a(Mode.o)
…“std :: ios_base :: Init :: Init()”,引用自:
___cxx_global_var_init in libZXingWidget.a(QRCodeReader-F470BE6889D3F76D.o) ___cxx_global_var_init in libZXingWidget.a(Decoder-3DF771F40A970F8E.o) ___cxx_global_var_init in libZXingWidget.a(FormatReader.o) ___cxx_global_var_init in libZXingWidget.a(QRCodeReader-C190599C861BFE46.o) ___cxx_global_var_init in libZXingWidget.a(DecodeHints.o) ___cxx_global_var_init in libZXingWidget.a(BinaryBitmap.o) ___cxx_global_var_init in libZXingWidget.a(DecoderResult.o)
等等…
我正在运行Xcode 4.5.2。 我已经将main.m重命名为main.mm,我的视图控制器也从.m重命名为.mm,架构无处不在是“armv7 armv7s”。
叹…
更新
有人在苹果devforums有我的问题的答案:
看起来你有不匹配的C ++标准库。 您的项目的构build设置使用了clang的C ++标准库,但libZXingWidget.a被编译为使用GNU C ++标准库。
试试这个:打开ZXingWidget.xcodeproj并将“C ++标准库”设置为“libc ++”,然后清理所有内容并重build。
如果不行的话,可以在你的项目和ZXingWidget.xcodeproj中将“C ++ Standard Library”设置为“libstdc ++”
第一个build议做了窍门。
我通过更改拖放到xcode的项目上的一个值来解决这个问题。
组:
只生成活动架构 – >debugging – >否
希望有助于人:)!
这解决了我的问题。 没有别的工作。
可能还需要将ZXingWidget目标的“仅生成活动架构”标志设置为“否”。
我已经按照上面的所有build议,而且一切都编译好,但仍然失败,错误消息:
Undefined symbols for architecture armv7: "_CVPixelBufferLockBaseAddress", referenced from:-[ZXingWidgetController captureOutput:didOutputSampleBuffer:fromConnection:] in libZXingWidget.a(ZXingWidgetController.o) "_CVPixelBufferGetBytesPerRow", referenced from:-[ZXingWidgetController captureOutput:didOutputSampleBuffer:fromConnection:] in libZXingWidget.a(ZXingWidgetController.o) "_CVPixelBufferGetWidth", referenced from:-[ZXingWidgetController captureOutput:didOutputSampleBuffer:fromConnection:] in libZXingWidget.a(ZXingWidgetController.o) "_CVPixelBufferGetBaseAddress", referenced from:-[ZXingWidgetController captureOutput:didOutputSampleBuffer:fromConnection:] in libZXingWidget.a(ZXingWidgetController.o) "_kCVPixelBufferPixelFormatTypeKey", referenced from:-[ZXingWidgetController initCapture] in libZXingWidget.a(ZXingWidgetController.o) "_CVPixelBufferGetHeight", referenced from:-[ZXingWidgetController captureOutput:didOutputSampleBuffer:fromConnection:] in libZXingWidget.a(ZXingWidgetController.o) "_CVPixelBufferUnlockBaseAddress", referenced from:-[ZXingWidgetController captureOutput:didOutputSampleBuffer:fromConnection:] in libZXingWidget.a(ZXingWidgetController.o)ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)
所以,你添加CoreVideo.framework,编译就OK了。
我多次去了所有的事情,经过无数的尝试,结果我只需要清理我的项目。 将C ++语言方言和C ++标准库更改为编译器默认值后,这是必要的。 我总是做一些简单的事情,但是我错过了,浪费了30分钟。