菜鸟教程小白 发表于 2022-12-13 05:24:22

c++ - boost iOS链接错误


                                            <p><p>我有一个 C++ 库,它严重依赖于我正在尝试为 iOS8 编译的 boost。我使用 Daniel Rosser 的脚本为 iOS 编译 boost-1.57.0:
<a href="https://github.com/danoli3/ofxiOSBoost" rel="noreferrer noopener nofollow">https://github.com/danoli3/ofxiOSBoost</a> </p>

<p>我修改了脚本,让它也构建了 boost 的 <code>serialization</code> 库,一切看起来都很好。</p>

<p>但是,当我在 XCode 中编译我的库时,我得到:</p>

<pre><code>Undefined symbols for architecture x86_64:
&#34;boost::archive::detail::shared_ptr_helper::shared_ptr_helper()&#34;, referenced from:
      eos::portable_iarchive::portable_iarchive(std::__1::basic_istream&lt;char, std::__1::char_traits&lt;char&gt; &gt;&amp;, unsigned int) in data_receiver.o
      eos::portable_oarchive::portable_oarchive(std::__1::basic_streambuf&lt;char, std::__1::char_traits&lt;char&gt; &gt;&amp;, unsigned int) in tcp_server.o
&#34;boost::archive::detail::shared_ptr_helper::~shared_ptr_helper()&#34;, referenced from:
      eos::portable_iarchive::portable_iarchive(std::__1::basic_istream&lt;char, std::__1::char_traits&lt;char&gt; &gt;&amp;, unsigned int) in data_receiver.o
      eos::portable_iarchive::~portable_iarchive() in data_receiver.o
      eos::portable_oarchive::portable_oarchive(std::__1::basic_streambuf&lt;char, std::__1::char_traits&lt;char&gt; &gt;&amp;, unsigned int) in tcp_server.o
      eos::portable_oarchive::~portable_oarchive() in tcp_server.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
</code></pre>

<p>它似乎坚持使用 boost::archive 库中的 shared_ptr_helper() 函数。我有点困惑,因为我认为这部分 boost 没有编译,它都是头文件,所以我不确定是什么导致了“错误的架构”错误。是否有另一个 boost 库实际上定义了我没有编译的这个方法? </p>

<p>稍后...这里是 eos::portable_iarchive 构造函数代码(这似乎是导致错误的原因——oarchive 代码几乎相同)</p>

<pre><code>namespace eos {

    // forward declaration
    class portable_iarchive;

    typedef boost::archive::basic_binary_iprimitive&lt;
            portable_iarchive
    #if BOOST_VERSION &lt; 103400
            , std::istream
    #else
            , std::istream::char_type
            , std::istream::traits_type
    #endif
    &gt; portable_iprimitive;

    /**
   * \brief Portable binary input archive using little endian format.
   *
   * This archive addresses integer size, endianness and floating point types so
   * that data can be transferred across different systems. There may still be
   * constraints as to what systems are compatible and the user will have to take
   * care that e.g. a very large int being saved on a 64 bit machine will result
   * in a portable_archive_exception if loaded into an int on a 32 bit system.
   * A possible workaround to this would be to use fixed types like
   * boost::uint64_t in your serialization structures.
   *
   * \note The class is based on the portable binary example by Robert Ramey and
   *         uses Beman Dawes endian library plus fp_utilities by Johan Rade.
   */
    class portable_iarchive : public portable_iprimitive

            // the example derives from common_oarchive but that lacks the
            // load_override functions so we chose to stay one level higher
            , public boost::archive::basic_binary_iarchive&lt;portable_iarchive&gt;

    #if BOOST_VERSION &gt;= 103500
            // mix-in helper class for serializing shared_ptr
            , public boost::archive::detail::shared_ptr_helper
    #endif
    {
            // only needed for Robert&#39;s hack in basic_binary_iarchive::init
            friend class boost::archive::basic_binary_iarchive&lt;portable_iarchive&gt;;

            // workaround for gcc: use a dummy struct
            // as additional argument type for overloading
            template &lt;int&gt; struct dummy { dummy(int) {}};

            // loads directly from stream
            inline signed char load_signed_char()
            {
                  signed char c;
                  portable_iprimitive::load(c);
                  return c;
            }

            // archive initialization
            void init(unsigned flags)
            {
                  using namespace boost::archive;
                  archive_version_type input_library_version(3);

                  // it is vital to have version information!
                  // if we don&#39;t have any we assume boost 1.33
                  if (flags &amp; no_header)
                            set_library_version(input_library_version);

                  // extract and check the magic eos byte
                  else if (load_signed_char() != magic_byte)
                            throw archive_exception(archive_exception::invalid_signature);

                  else
                  {
                            // extract version information
                            operator&gt;&gt;(input_library_version);

                            // throw if file version is newer than we are
                            if (input_library_version &gt; archive_version)
                                    throw archive_exception(archive_exception::unsupported_version);

                            // else set the library version accordingly
                            else set_library_version(input_library_version);
                  }
            }
public:
      /**
         * \brief Constructor on a stream using ios::binary mode!
         *
         * We cannot call basic_binary_iprimitive::init which tries to detect
         * if the binary archive stems from a different platform by examining
         * type sizes.
         *
         * We could have called basic_binary_iarchive::init which would create
         * the boost::serialization standard archive header containing also the
         * library version. Due to efficiency we stick with our own.
         */
      portable_iarchive(std::istream&amp; is, unsigned flags = 0)
      #if BOOST_VERSION &lt; 103400
                : portable_iprimitive(is, flags &amp; boost::archive::no_codecvt)
      #else
                : portable_iprimitive(*is.rdbuf(), flags &amp; boost::archive::no_codecvt)
      #endif
                , boost::archive::basic_binary_iarchive&lt;portable_iarchive&gt;(flags)
      {
                init(flags);
      }

#if BOOST_VERSION &gt;= 103400
      portable_iarchive(std::streambuf&amp; sb, unsigned flags = 0)
                : portable_iprimitive(sb, flags &amp; boost::archive::no_codecvt)
                , boost::archive::basic_binary_iarchive&lt;portable_iarchive&gt;(flags)
      {
                init(flags);
      }
#endif

      //! Load narrow strings.
      void load(std::string&amp; s)
      {
                portable_iprimitive::load(s);
      }

#ifndef BOOST_NO_STD_WSTRING
      /**
         * \brief Load wide strings.
         *
         * This is rather tricky to get right for true portability as there
         * are so many different character encodings around. However, wide
         * strings that are encoded in one of the Unicode schemes only need
         * to be _transcoded_ which is a lot easier actually.
         *
         * We generate the output string to be encoded in the system&#39;s native
         * format, ie. UTF-16 on Windows and UTF-32 on Linux machines. Don&#39;t
         * know about Mac here so I can&#39;t really say about that.
         */
      void load(std::wstring&amp; s)
      {
                std::string utf8;
                load(utf8);
                s = boost::from_utf8(utf8);
      }
</code></pre>

<p>等等</p>

<p>这些行特别有趣:</p>

<pre><code>#if BOOST_VERSION &gt;= 103500
      // mix-in helper class for serializing shared_ptr
      , public boost::archive::detail::shared_ptr_helper
#endif
</code></pre>

<p>注释掉它们使我的构建成功,但我仍然对无法使用 shared_ptr_helper() 感到不高兴。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>首先确定:</p>

<ul>
<li>您必须将项目或目标build设置更改为 c++11</li>
</ul>

<blockquote>
<p>Under Apple LLVM 6.0 - Language - C++ make the following changes</p>

<p>C++ Language Dialect to C++11 [-std=c++11] C++ Standard Library to
libc++ (LLVM C++ standard library with C++11 support)</p>
</blockquote>

<p>否则我认为这可能与以下链接的 EOS - Boost Bug (Boost >= 1.56.0)有关</p>

<p>问题:<a href="https://epa.codeplex.com/workitem/2456" rel="noreferrer noopener nofollow">https://epa.codeplex.com/workitem/2456</a> </p>

<p>我还快速查看了构建脚本,以确保它肯定会将 Boost 序列化库添加到每个架构的 lipo boost 存档中,是的,它肯定都在那里。</p></p>
                                   
                                                <p style="font-size: 20px;">关于c&#43;&#43; - boost iOS链接错误,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/28569298/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/28569298/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: c&#43;&#43; - boost iOS链接错误