Previously I had made a Card.IO binding manually. It was compiling, so was the project that used it, but it would crash too often.

Now I'm trying to recreate the binding using ObjectiveSharpie from scratch. The binding project compiles but when I reference it from another project I get compiler errors shown below.

It was showing AVFoundation framework items as "Undefined symbols..." so under IOS Build options in Xamarin I have "-cxx" option. I tried various combinations of ways to add frameworks to the project: - modified [assembly: LinkWith(..., Frameworks="...")] in CardIO binding project. This results in unrecognized CardIO namespace in my main project - added -gcc_flags "-framework ...". This results in "framework not found" message from the compiler I finally resolved the AVFoundation by including a using AVFoundation, then requesting the type name of one if its classes so the linker doesn't optimize it away - ugly hack in my book.

In the error below it looks like there are more frameworks missing, on top of that I believe the std::... ones should have been resolved by using the "-cxx" parameter

I'm out of ideas how to make this binding compile and work properly.

Undefined symbols for architecture armv7:
  "_AudioServicesPlayAlertSound", referenced from:
      -[CardIOCameraViewController vibrate] in libCardIO.a(CardIOCameraViewController.o)
  "_CMGetAttachment", referenced from:
      -[CardIOVideoStream captureOutput:didOutputSampleBuffer:fromConnection:] in libCardIO.a(CardIOVideoStream.o)
  "_CMSampleBufferGetImageBuffer", referenced from:
      -[CardIOVideoFrame process] in libCardIO.a(CardIOVideoFrame.o)
  "_CVPixelBufferGetBaseAddressOfPlane", referenced from:
      +[CardIOIplImage imageFromYCbCrBuffer:plane:] in libCardIO.a(CardIOIplImage.o)
  "_CVPixelBufferGetBytesPerRowOfPlane", referenced from:
      +[CardIOIplImage imageFromYCbCrBuffer:plane:] in libCardIO.a(CardIOIplImage.o)
  "_CVPixelBufferGetHeightOfPlane", referenced from:
      +[CardIOIplImage imageFromYCbCrBuffer:plane:] in libCardIO.a(CardIOIplImage.o)
  "_CVPixelBufferGetWidthOfPlane", referenced from:
      +[CardIOIplImage imageFromYCbCrBuffer:plane:] in libCardIO.a(CardIOIplImage.o)
  "_CVPixelBufferLockBaseAddress", referenced from:
      -[CardIOVideoFrame process] in libCardIO.a(CardIOVideoFrame.o)
  "_CVPixelBufferUnlockBaseAddress", referenced from:
      -[CardIOVideoFrame process] in libCardIO.a(CardIOVideoFrame.o)
  "_OBJC_CLASS_$_EAGLContext", referenced from:
      objc-class-ref in libCardIO.a(CardIOGPURenderer.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char const*, unsigned long, unsigned long) const", referenced from:
      cv::CommandLineParser::CommandLineParser(int, char const* const*, char const*)in libCardIO.a(cmdparser.o)
      (anonymous namespace)::split_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)in libCardIO.a(cmdparser.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char, unsigned long) const", referenced from:
      cv::CommandLineParser::CommandLineParser(int, char const* const*, char const*)in libCardIO.a(cmdparser.o)
      (anonymous namespace)::del_space(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)in libCardIO.a(cmdparser.o)
      cv::CommandLineParser::printParams()      in libCardIO.a(cmdparser.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::rfind(char, unsigned long) const", referenced from:
      (anonymous namespace)::del_space(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)in libCardIO.a(cmdparser.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::compare(char const*) const", referenced from:
      cv::CommandLineParser::CommandLineParser(int, char const* const*, char const*)in libCardIO.a(cmdparser.o)
      cv::CommandLineParser::printParams()      in libCardIO.a(cmdparser.o)
      bool cv::CommandLineParser::get<bool>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)in libCardIO.a(cmdparser.o)
  "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
有帮助吗?

解决方案 2

After a lot of guesswork, trial-error and searching for each particular error in the output I came up with a solution that works, add this attribute to the .linkwith.cs file in the binding project:

[assembly: LinkWith ("libCardIO.a", IsCxx=true, LinkTarget= LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator, ForceLoad = true
                     ,Frameworks = "AVFoundation AudioToolbox CoreMedia CoreVideo OpenGLES MobileCoreServices"
                     ,LinkerFlags = "-ObjC -lc++")]

I had assumed that adding

-cxx -gcc_flags "-lstdc++"

to the main project's iOS build should do the same thing but that wasn't the case, with or without these additional compiler parameters the binding wasn't building.

If you need a copy of the binding project just ask.

其他提示

This was an ugly one, but an easy fix in the end. In the target's build settings, in "Other Linker Flags," I have the following:

-lstdc++ -ObjC -lc++

That is, libCardIO is requiring both -lstdc++ and -lc++.

Also, make sure you have set "Link With Standard Libraries" to "Yes".

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top