如何在Visual Studio 2015中构建log4cxx

How to build log4cxx in Visual Studio 2015

本文关键字:构建 log4cxx 2015 Studio Visual      更新时间:2023-10-16

我一直在使用log4cxx,它可以满足我的需求。我们正在迁移到VS 2015,我发现Visual Studio 2015中的编译器在我尝试重建log4cxx 0.10.0.1时抛出错误。如果我将项目工具集更改为Visual Studio 2013 (v120),则构建仍然有效,但当我尝试使用它时,它在运行时存在问题。请参阅下面的错误消息,它在多个场合发生。有没有人找到一种方法来构建log4cxx正确与Visual Studio 2015?

4>....Log4cxxlog4cxxapache-log4cxx-0.10.0srcmainincludelog4cxx/layout.h(90): error C2248: 'log4cxx::helpers::ObjectImpl::ObjectImpl': cannot access private member declared in class 'log4cxx::helpers::ObjectImpl'
4>....Log4cxxlog4cxxapache-log4cxx-0.10.0srcmainincludelog4cxx/helpers/objectimpl.h(43): note: see declaration of 'log4cxx::helpers::ObjectImpl::ObjectImpl'
4>....SDKSLog4cxxlog4cxxapache-log4cxx-0.10.0srcmainincludelog4cxx/helpers/objectimpl.h(28): note: see declaration of 'log4cxx::helpers::ObjectImpl'
4>....SDKSLog4cxxlog4cxxapache-log4cxx-0.10.0srcmainincludelog4cxx/layout.h(90): note: This diagnostic occurred in the compiler generated function 'log4cxx::Layout::Layout(const log4cxx::Layout &)'

我有同样的问题,并找到了一个修复希望。

问题是基类ObjectImpl的定义:

    class LOG4CXX_EXPORT ObjectImpl : public virtual Object
    {
    public:
        ObjectImpl();
        virtual ~ObjectImpl();
        void addRef() const;
        void releaseRef() const;
    protected:
        mutable unsigned int volatile ref;
    private:
        //
        //   prevent object copy and assignment
        //
        ObjectImpl(const ObjectImpl&);
        ObjectImpl& operator=(const ObjectImpl&);
    };

可以看到,类隐藏了复制构造函数和复制赋值操作符,因为使用引用计数器的设计没有合适的实现。使用共享指针会更好。

新的stl实现为其集合类使用move语义,当没有带有move语义的复制构造函数和复制赋值操作符时,它必须使用标准操作符,而标准操作符是不可用的。

为了解决这个问题,我们必须将移动操作符添加到以下类中:ObjectImpl, Layout, Filter, PatternConverter, TriggeringPolicy和RollingPolicyBase。

这是我对ObjectImpl的新实现:

    class LOG4CXX_EXPORT ObjectImpl : public virtual Object
    {
    public:
        ObjectImpl();
        virtual ~ObjectImpl();
        void addRef() const;
        void releaseRef() const;
        // added for VS2015
        ObjectImpl(ObjectImpl && o)
        {
            ref = o.ref;
            o.ref = 0;
        }
        ObjectImpl& operator=(ObjectImpl && o)
        {
            ref = o.ref;
            o.ref = 0;
            return *this;
        }
        // -----
    protected:
        mutable unsigned int volatile ref;
    private:
        //
        //   prevent object copy and assignment
        //
        ObjectImpl(const ObjectImpl&);
        ObjectImpl& operator=(const ObjectImpl&);
    };

还有一个例子。其余类类似:

    class LOG4CXX_EXPORT Filter : public virtual OptionHandler,
        public virtual helpers::ObjectImpl
    {
        /**
        Points to the next filter in the filter chain.
        */
        FilterPtr next;
    public:
        Filter();
        // added for VS2015
        Filter(Filter && o)
            : helpers::ObjectImpl(std::move(o))
            , next( o.next )
        { }
        Filter& operator=(Filter && o)
        {
            helpers::ObjectImpl::operator=(std::move(o));
            next = o.next;
            return *this;
        }
        // end of added for VS2015
        ...

我希望这对你有帮助。

一个同事遇到了这个问题,他找到了File> New> Project> Visual C++,选择了Install Windows XP Support for C++。奇怪的是,我从来没有这样做过,但我也从来没有遇到过同样的问题。

下面的代码是正确的答案apache-log4cxx-0.10.0 vs2015

// objectimpl.h
namespace log4cxx
{
   namespace helpers
   {
      /** Implementation class for Object.*/
      class LOG4CXX_EXPORT ObjectImpl : public virtual Object
      {
      public:
         ObjectImpl();
         virtual ~ObjectImpl();
         void addRef() const;
         void releaseRef() const;
      protected:
         mutable unsigned int volatile ref;
        //private:
                        //
            //   prevent object copy and assignment
            //
        ObjectImpl(const ObjectImpl&);
        ObjectImpl& operator=(const ObjectImpl&);
      };
   }
}
// objectimpl.cpp
ObjectImpl::ObjectImpl(const ObjectImpl& o)
{
    ref = o.ref;
    o.ref = 0;
}
ObjectImpl& ObjectImpl::operator=(const ObjectImpl& o)
{
    ref = o.ref;
    o.ref = 0;
    return *this;
}