.o文件中导出的符号未在.dylib中导出 我最近遇到了在共享小工具(.DyLIB文件)中从McVIEKS(Oxx7.94,XCODE 5.1)编译C++代码(.O文件)中出现错误的问题。一个特定实现类中的键符号似乎在.o文件中导出,而不是从包含.o的.dylib文件中导出

.o文件中导出的符号未在.dylib中导出 我最近遇到了在共享小工具(.DyLIB文件)中从McVIEKS(Oxx7.94,XCODE 5.1)编译C++代码(.O文件)中出现错误的问题。一个特定实现类中的键符号似乎在.o文件中导出,而不是从包含.o的.dylib文件中导出,c++,osx-mavericks,xcode5.1,crtp,C++,Osx Mavericks,Xcode5.1,Crtp,我们的代码库被分解成模块。我们大量使用了奇怪的循环模板模式(CRTP)。代码草图如下所示: #include <string> class ExprVec; class Operator { public: virtual bool operator()(bool &result, ExprVec const &args) const = 0; virtual bool operator()(int32_t &result, ExprVec con

我们的代码库被分解成模块。我们大量使用了奇怪的循环模板模式(CRTP)。代码草图如下所示:

#include <string>
class ExprVec;

class Operator
{
 public:
  virtual bool operator()(bool &result, ExprVec const &args) const = 0;
  virtual bool operator()(int32_t &result, ExprVec const &args) const = 0;
  virtual bool operator()(double &result, ExprVec const &args) const = 0;
  virtual bool operator()(std::string &result, ExprVec const &args) const = 0;
};

template <class IMPL>
class OperatorShim : public Operator
{
 public:
  bool operator()(bool &result, ExprVec const &args) const
  {
    return static_cast<IMPL const *>(this)->calc(result, args);
  }
  bool operator()(int32_t &result, ExprVec const &args) const
  {
    return static_cast<IMPL const *>(this)->calc(result, args);
  }
  bool operator()(double &result, ExprVec const &args) const
  {
    return static_cast<IMPL const *>(this)->calc(result, args);
  }
  bool operator()(std::string &result, ExprVec const &args) const
  {
    return static_cast<IMPL const *>(this)->calc(result, args);
  }
};

template <typename T>
class OperatorImpl : public OperatorShim<OperatorImpl<T> >
{
 public:
  // implemented by derived classes
  virtual bool calc(T &result, ExprVec const &args) const = 0;

  // default methods
  template <typename U>
  bool calc <U &result, ExprVec const &args) const
  {
    // throw wrong-type exception
    return false;
  }
};

template class OperatorImpl<bool>;
template class OperatorImpl<int32_t>;
template class OperatorImpl<double>;
template class OperatorImpl<std::string>;
所讨论的文件是…/src/expr/OperatorImpl.{hh,cc,o}和…/src/expr/.libs/libPlexilExpr.0.dylib。生成动态库文件的命令是:

libtool: link: g++ -dynamiclib -Wl,-undefined -Wl,dynamic_lookup -o .libs/libPlexilExpr.0.dylib  .libs/libPlexilExpr_la-Alias.o .libs/libPlexilExpr_la-Array.o .libs/libPlexilExpr_la-ArrayImpl.o .libs/libPlexilExpr_la-ArithmeticFunctionFactory.o .libs/libPlexilExpr_la-ArithmeticOperators.o .libs/libPlexilExpr_la-ArrayOperators.o .libs/libPlexilExpr_la-ArrayReference.o .libs/libPlexilExpr_la-ArrayVariable.o .libs/libPlexilExpr_la-Assignable.o .libs/libPlexilExpr_la-AssignableImpl.o .libs/libPlexilExpr_la-BooleanOperators.o .libs/libPlexilExpr_la-CommandHandle.o .libs/libPlexilExpr_la-Comparisons.o .libs/libPlexilExpr_la-ConcreteExpressionFactory.o .libs/libPlexilExpr_la-Constant.o .libs/libPlexilExpr_la-Expression.o .libs/libPlexilExpr_la-ExpressionConstants.o .libs/libPlexilExpr_la-ExpressionFactories.o .libs/libPlexilExpr_la-ExpressionFactory.o .libs/libPlexilExpr_la-ExpressionImpl.o .libs/libPlexilExpr_la-ExpressionListener.o .libs/libPlexilExpr_la-ExprVec.o .libs/libPlexilExpr_la-Function.o .libs/libPlexilExpr_la-FunctionFactory.o .libs/libPlexilExpr_la-NodeConstants.o .libs/libPlexilExpr_la-NodeConstantExpressions.o .libs/libPlexilExpr_la-NotifierImpl.o .libs/libPlexilExpr_la-OperatorImpl.o .libs/libPlexilExpr_la-PlexilExpr.o .libs/libPlexilExpr_la-StringOperators.o .libs/libPlexilExpr_la-UserVariable.o .libs/libPlexilExpr_la-Value.o .libs/libPlexilExpr_la-ValueType.o   -lm -lpthread -ldl  -O2   -install_name  /Users/chucko/src/plexil-3-new-exp/lib/libPlexilExpr.0.dylib -compatibility_version 1 -current_version 1.0 -Wl,-single_module

这是我的编码错误造成的吗?我尝试了许多不同的方法,但无法解决问题。

1:构建动态库的命令行是什么?2:“nm”报告是什么?请参见编辑的问题描述,了解如何重现。我是从另一台计算机上输入的,而不是在发生问题的计算机上输入的,因此我手头没有“nm”输出nm'报告与OperatorShim中的类型对应的所有calc()方法都存在于.o文件中,但模板化的默认方法不是从.dylib导出的。只是尝试从svn生成该代码。这对我有用。看起来你解决了问题…iCalus3是正确的。我回到了以前的方法,其中模板化的calc()方法实现位于头文件中,而不是单独的.cc文件中。我将修改上面的说明以获得以前的版本。如果可能的话,我仍然想解决链接器问题。
libtool: link: g++ -dynamiclib -Wl,-undefined -Wl,dynamic_lookup -o .libs/libPlexilExpr.0.dylib  .libs/libPlexilExpr_la-Alias.o .libs/libPlexilExpr_la-Array.o .libs/libPlexilExpr_la-ArrayImpl.o .libs/libPlexilExpr_la-ArithmeticFunctionFactory.o .libs/libPlexilExpr_la-ArithmeticOperators.o .libs/libPlexilExpr_la-ArrayOperators.o .libs/libPlexilExpr_la-ArrayReference.o .libs/libPlexilExpr_la-ArrayVariable.o .libs/libPlexilExpr_la-Assignable.o .libs/libPlexilExpr_la-AssignableImpl.o .libs/libPlexilExpr_la-BooleanOperators.o .libs/libPlexilExpr_la-CommandHandle.o .libs/libPlexilExpr_la-Comparisons.o .libs/libPlexilExpr_la-ConcreteExpressionFactory.o .libs/libPlexilExpr_la-Constant.o .libs/libPlexilExpr_la-Expression.o .libs/libPlexilExpr_la-ExpressionConstants.o .libs/libPlexilExpr_la-ExpressionFactories.o .libs/libPlexilExpr_la-ExpressionFactory.o .libs/libPlexilExpr_la-ExpressionImpl.o .libs/libPlexilExpr_la-ExpressionListener.o .libs/libPlexilExpr_la-ExprVec.o .libs/libPlexilExpr_la-Function.o .libs/libPlexilExpr_la-FunctionFactory.o .libs/libPlexilExpr_la-NodeConstants.o .libs/libPlexilExpr_la-NodeConstantExpressions.o .libs/libPlexilExpr_la-NotifierImpl.o .libs/libPlexilExpr_la-OperatorImpl.o .libs/libPlexilExpr_la-PlexilExpr.o .libs/libPlexilExpr_la-StringOperators.o .libs/libPlexilExpr_la-UserVariable.o .libs/libPlexilExpr_la-Value.o .libs/libPlexilExpr_la-ValueType.o   -lm -lpthread -ldl  -O2   -install_name  /Users/chucko/src/plexil-3-new-exp/lib/libPlexilExpr.0.dylib -compatibility_version 1 -current_version 1.0 -Wl,-single_module