在使用Xcode 4.5中的ZXing库时,出现了针对armv7架构的未定义符号。

37

我想做什么

在我的iPhone项目中集成二维码阅读器框架Zxing。我从这里检出了ZXing SDK。我运行了带有ZXing的示例项目ScanTest,没有任何问题。但是当我尝试将库与我的项目集成时,遇到了提到的错误。

项目规格

  • 目标操作系统:iOS 6.0
  • 部署目标:iOS 5.0或以上。
  • 测试设备:iPhone 4和iPhone 3GS。
  • Xcode:Xcode 4.5.1
  • ZXing版本:2.0

问题

当我按照ZXing自述文件中的每个集成步骤构建时,我遇到了构建错误,例如

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上的这个这个这个这个这个这个这个线程,所有线程都出现了相同的错误信息。没有一个解决方案适用于我。

然后我在ZXing论坛中找到了这个已关闭的线程,讨论了相同的问题。根据那个讨论,有一些可能的解决方案(对某些人有效)

第一个错误(可能)是因为您没有将main.m重命名为main.mm。第二个错误(可能)是因为您没有链接widget库。

我也将我的main.m重命名,核对了是否添加了库,只发现我肯定有添加。所以这不是解决方案。

当我将库的架构更改为“标准(armv7,armv7s)”以匹配我的主项目后,我能够成功编译应用程序。

我的项目、目标、库项目(针对调试、分发、发布)的架构都给出了标准(armv7,armv7s)。所以也没有运气。

然后他们关闭了这个问题,说:

ZXing项目已更新,添加了armv7s arch并删除了armv6 arch。这些更改是必需的:(1)为iPhone 5构建,它是armv7s,(2)为了构建,因为Xcode 4.5不包括对armv6的支持。如果您有自己的项目文件,您需要自己进行这些更改。这些是一般性的更改,而不是特定于zxing的更改,因此如果遇到问题,您可以在像StackOverflow这样的一般论坛中获得更多/更快的帮助。

所以,我在StackOverflow这里。

还有一点

在ZXing集成的README文件中,集成的第一步是:

1)在“ zxing / iphone / ZXingWidget / </


您好,我根据您的评论成功地集成了该项目。但是在成功集成后,我仍然遇到错误。我运行了扫描测试(我们项目中的代码类型)示例,但尝试了条形码示例。我从BarcodeExample导入了几个文件。我得到了“ResultParser”类的重复接口定义错误。我该如何解决这个问题? - kumar
对我来说,是将libc++.dylib添加到我的项目中。参见:https://dev59.com/YOo6XIcBkEYKwwoYORsV - micahnyc
7个回答

57

好的,最终我成功了。对于未来遇到此问题的人,请注意:

  1. 将 main.m 文件重命名为 main.mm。

    ZXing 的 README 文件解释了我们为什么需要这样做。

    有时当您尝试使用 ZXingWidgetController 构建自己的项目时,可能会出现链接器错误,例如“undefined reference to”。如果此错误看起来像是 C++ 未定义引用,则将 main.m 重命名为 main.mm(Objective-C++ 源代码后缀)可能会解决问题。

  2. 将使用 ZXing 库函数的文件(ViewController/View)也重命名为 .mm 扩展名。

  3. 检查整个项目的架构设置。在您的项目设置、目标设置和添加到主项目中的 ZXing 项目及其目标设置中,将架构有效架构设置为armv7 armv7s

  4. 在主项目中-> 构建设置 中查找选项C++语言方言C++标准库。为两者都选择选项“编译器默认值”。(这是我错过的步骤,因为最新的 XCode 模板具有与旧版本不同的编译器默认设置。)

  5. 您还可能需要将 ZXingWidget 的“仅构建有效架构”标志设置为 NO。在我的情况下,此字段已经是 NO

These fixed the issue for me..

更新

在2013年12月,Google已经停用了ZXing iOS/Objective C端口。因此,iOS的Zxing项目不再得到维护和更新以适应新的iOS版本。此外,Zxing没有支持Arm64架构,这是新XCode版本中的标准架构之一。
因此,开发人员被鼓励转移到本机苹果框架来读取条形码,该框架从iOS7开始提供。请参见此处以获取逐步教程。

@smparkes 关于(4),不,我没有定制它们。我使用Xcode 4.5.1创建了一个新项目(空项目模板),它具有不同的编译器设置。 - Krishnabhadra
同意。如果您想在邮件列表上发布补丁或建议的措辞,或者创建一个问题,那就太好了。感谢您发现这个问题。 - smparkes
2
(4)是一个神奇的解决方案,当你通过cocoapods将ZXing添加到新创建的XCode 4.5.2项目中时,可以使用它。 - Ben Clayton
请还附上jumbob答案。对我来说,将两个答案都添加到我的项目中有效 ;) - Kasas
我尝试了很多次,但在导入ZXing库后无法修复编译时出现的错误。@Krishnabhadra,你真的节省了我很多时间。给你点赞。 - Suraj Mirajkar
显示剩余6条评论

10

我已经按照以上所有建议进行操作,虽然一切都可以编译成功,但连接失败了:

"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"。

叹气...

更新

Apple 开发论坛上的某个人给出了解决方案:

  

看起来您的 C++ 标准库不匹配。 您项目的构建设置正在使用 clang 的 C++ 标准库,但 libZXingWidget.a 是使用 GNU C++ 标准库编译的。

     

尝试此操作:打开 ZXingWidget.xcodeproj,并将 "C++ 标准库" 设置为 "libc++",然后清理一切并重新构建。

     

如果这不起作用,请在您的项目和 ZXingWidget.xcodeproj 中将 "C++ 标准库" 设置为 "libstdc++"

第一个建议解决了我的问题。


6

我通过更改您拖放到Xcode中的项目中的一个值来解决了它。

enter image description here

设置:

仅构建活动架构 -> 调试 -> 否

希望这对大家有所帮助 :)!


6
这对我解决了问题,其他方法都没用。

在此输入图片描述


这个方案帮助我启动了Cocos2d-x v2.2.2 C++项目。谢谢! - Sound Blaster

4
可能还需要将ZXingWidget目标的“仅构建活动架构”标志设置为“NO”。

1
我已经按照以上建议进行了操作,虽然一切都编译成功了,但是仍然失败了,错误信息如下:
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,编译就会顺利通过。


0

我反复检查了所有内容,经过无数次尝试后,结果发现我只需要清理项目即可。在将C++语言方言和C++标准库更改为编译器默认值后,这是必要的。这是我经常做的简单操作,但我错过了它,浪费了30分钟。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接