iOS Question [SOLVED] Static lib using external framework

Discussion in 'iOS Questions' started by JordiCP, Jun 14, 2018.

  1. JordiCP

    JordiCP Well-Known Member Licensed User

    I have been searching related threads but there aren't many and I couldn't find a clue that was useful for my problem.
    My goal is to be able to use some OpenCV functionality from inline ObjC. For this, I am trying to build a static lib that uses the opencv framework, and define a class with some methods that use this framework

    For this, first I made a very simple static library with XCode: created it, copy .h and .a files it to my local Mac, and then call its functions with inline Objective-C in my B4i app --> until here, everything works.

    Now, the complicated part, where I am stuck. What I have tried is:
    • Add OpenCV to the XCode project using cocoaPods (didn't succeed adding the framework, so I tried this approach and worked ok in XCode).
    • Then I add a couple of functions in the class (interface + implementacion) that use OpenCV, adding the needed headers --> the lib is compiled without errors.
    • Then I add the files to my local Mac Libs folder and do the same as before: try to call a method that uses a simple OpenCV function --> a lot of errors appear:
    Code:
    ...

    Undefined symbols 
    for architecture arm64:
      
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::at(unsigned long) const", referenced from:
          google::protobuf::io::Tokenizer::IsIdentifier(std::__
    1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in opencv2(tokenizer.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:
          google::protobuf::GlobalReplaceSubstring(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&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in opencv2(strutil.o)
      
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char, unsigned long) const", referenced from:
          cv::ocl::Device::Impl::Impl(void*) 
    in opencv2(ocl.o)
          _cvOpenFileStorage 
    in opencv2(persistence_c.o)
          google::protobuf::DescriptorBuilder::LookupSymbolNoPlaceholder(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&, google::protobuf::DescriptorBuilder::ResolveMode, bool) in opencv2(descriptor.o)
      
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::rfind(char, unsigned long) const", referenced from:
          _cvOpenFileStorage 
    in opencv2(persistence_c.o)
          google::protobuf::DescriptorPool::IsSubSymbolOfBuiltType(std::__
    1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const in opencv2(descriptor.o)
          google::protobuf::DescriptorBuilder::LookupSymbolNoPlaceholder(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&, google::protobuf::DescriptorBuilder::ResolveMode, bool) in opencv2(descriptor.o)
          google::protobuf::DescriptorPool::NewPlaceholderWithMutexHeld(std::__
    1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DescriptorPool::PlaceholderType) const in opencv2(descriptor.o)
          google::protobuf::DescriptorBuilder::AddSymbol(std::__
    1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::Message const&, google::protobuf::Symbol) in opencv2(descriptor.o)
          google::protobuf::DescriptorBuilder::AddPackage(std::__
    1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::Message const&, google::protobuf::FileDescriptor const*) in opencv2(descriptor.o)
          google::protobuf::FieldDescriptor::InternalTypeOnceInit() 
    const in opencv2(descriptor.o)
          ...
      
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::compare(unsigned long, unsigned long, char const*, unsigned long) const", referenced from:
          cv::dnn::experimental_dnn_v4::(anonymous namespace)::TFImporter::populateNet(cv::dnn::experimental_dnn_v4::Net) 
    in opencv2(tf_importer.o)
          cv::dnn::experimental_dnn_v4::(anonymous namespace)::addConstNodes(tensorflow::GraphDef&, std::__
    1::map<cv::String, int, std::__1::less<cv::String>, std::__1::allocator<std::__1::pair<cv::String const, int> > >&, std::__1::set<cv::String, std::__1::less<cv::String>, std::__1::allocator<cv::String> >&) in opencv2(tf_importer.o)
          cv::dnn::NetNeedsUpgrade(opencv_caffe::NetParameter 
    const&) in opencv2(caffe_io.o)
          cv::dnn::NetNeedsBatchNormUpgrade(opencv_caffe::NetParameter 
    const&) in opencv2(caffe_io.o)
          cv::dnn::UpgradeV0PaddingLayers(opencv_caffe::NetParameter 
    const&, opencv_caffe::NetParameter*) in opencv2(caffe_io.o)
          cv::dnn::UpgradeV0LayerParameter(opencv_caffe::V1LayerParameter 
    const&, opencv_caffe::V1LayerParameter*) in opencv2(caffe_io.o)
          cv::dnn::UpgradeV0LayerType(std::__
    1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in opencv2(caffe_io.o)
          ...
      
    "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
          void std::__
    1::vector<int, std::__1::allocator<int> >::__push_back_slow_path<int const>(int const&) in opencv2(system.o)
          void std::__
    1::vector<void*, std::__1::allocator<void*> >::__push_back_slow_path<void* const>(void* const&) in opencv2(system.o)
          void std::__
    1::vector<cv::ThreadData*, std::__1::allocator<cv::ThreadData*> >::__push_back_slow_path<cv::ThreadData* const>(cv::ThreadData* const&) in opencv2(system.o)
          std::__
    1::vector<void*, std::__1::allocator<void*> >::__append(unsigned long, void* const&) in opencv2(system.o)
          void std::__
    1::vector<int, std::__1::allocator<int> >::__push_back_slow_path<int const>(int const&) in opencv2(tf_importer.o)
          std::__
    1::vector<int, std::__1::allocator<int> >::__append(unsigned long) in opencv2(tf_importer.o)
          std::__
    1::vector<int, std::__1::allocator<int> >::__append(unsigned long, int const&) in opencv2(tf_importer.o)

    .....(a lot more, similar 
    to these)

    Has someone gone through the same process? Should I abandon the cocoa Pods way and go back to the framework, or it is not related? Perhaps my approach is totally wrong and there are simpler ways to get it.

    Thanks in advance!
     
  2. JanPRO

    JanPRO Well-Known Member Licensed User

    Hi,

    First of all, if you create your own custom library in Xcode, why do you want to use inline ObjC code? Instead of this, convert your main header file to a xml (with the attached tool here) and use your library directly in B4i.

    Cocoa pods should be fine, however from my experience I recommend you to use frameworks, because they are easier to add and your project is more tidied up. I have sucessfully used the OpenCV framework in custom libraries in the past.

    Your library doesn't contain the required arm64 architecture for iPhones, probably you have compiled your library with the simulator sdk. Change your build device to "Generic iOS Device". If you want to create a library which runs on iPhone & simulator then you need to create a fat library with the lipo tool.

    In B4i you have also the possibility to use the OpenCV framework directly with inline Objc code, add a reference to the framework with the #AdditionalLib tag.

    Jan
     
    JordiCP likes this.
  3. JordiCP

    JordiCP Well-Known Member Licensed User

    ...a lot of information here, thanks!

    I must be doing something really wrong. Before I was building the lib for a connected iPhone5S. Now I have just built the lib again for a generic iOS device, done the same process and the problem persists.

    Then I have removed my lib, and just referenced the opencv2.framework with #AdditionalLib , and the same sort of errors appear

    Code:
    (...)
    Undefined symbols 
    for architecture arm64:
      
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char, unsigned long) const", referenced from:
          cv::ocl::Device::Impl::Impl(void*) 
    in opencv2(ocl.o)
          _cvOpenFileStorage 
    in opencv2(persistence_c.o)
      
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::rfind(char, unsigned long) const", referenced from:
          _cvOpenFileStorage 
    in opencv2(persistence_c.o)
      
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::compare(unsigned long, unsigned long, char const*, unsigned long) const", referenced from:
          
    base64::Base64Writer::check_dt(char const*) in opencv2(persistence_base64.o)
      
    "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
    (...)

    I'm starting to think that perhaps my opencv2.framework file is not correct, will do some more tests in this direction
     
  4. JordiCP

    JordiCP Well-Known Member Licensed User

    no way :mad:. An empty project referencing opencv framework (3.4.1) throws all those errors

    Just for curiosity, which opencv framework did you use? Was the framework out-of-the-box or you built it yourself?


    -- EDIT --

    Finally I could solve it with the latest framework and the hint given here :)
     
    Last edited: Jun 15, 2018
    JanPRO likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice