如何在 Visual Studio 2015 年构建 log4cxx

How to build log4cxx in Visual Studio 2015

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

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

我遇到了同样的问题,希望找到解决方法。

问题是base的定义class 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&);
    };

如你所见,class隐藏了一个拷贝构造函数和拷贝赋值运算符,因为使用引用计数器的设计没有合适的实现。使用共享指针会更好。

新的 stl 实现对其集合 classes 使用移动语义,当没有具有移动语义的复制构造函数和复制赋值运算符时,它必须使用不可用的标准运算符。

要解决这个问题,我们必须将移动运算符添加到以下 class 中: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个类似:

    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.0vs2015

// 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;
}