如何使用本地c++库的c++ /CLI包装器库导出多个类

How to export multiple classes with a C++/CLI wrapper library for a native C++ library

本文关键字:c++ CLI 何使用 库的 包装      更新时间:2023-10-16

我有一个本地c++库(让我们称之为CoreLib.dll),它暴露了两个类:

  • Core.h
  • Atom.h

我有一个CLI/c++包装器(让我们称之为CoreWrapper.dll),它允许。net项目实例化CoreAtom对象:

  • CoreDotNet.h
  • AtomDotNet.h(包括Atom.h和CoreDotNet.h)

当我编译CoreWrapper时,只有CoreDotNet.h被编译,AtomDotNet.h被忽略。如果我想编译AtomDotNet.h,那么我必须将它包含在CoreDotNet.h中,但这会导致CoreDotNet.h中的编译器错误:

error C2011: 'CoreWrapperNS::CoreDotNet' : 'class' type redefinition

下面是我所做的一些基本代码:

#pragma once // <-- should protect from class type redefinition
#include "Core.h"
//#include "AtomDotNet.h" // uncommenting causes compiler error C2011
using namespace CoreNS;
namespace CoreWrapperNS
{
    public ref class CoreDotNet
    {
    public:
        // Allows users to instantiate a core object
        CoreDotNet();
        CoreDotnet(Core* core);
        //... destructor follows
    };
}

下面是AtomDotNet.h文件:

#pragma once // <-- should protect from class type redefinition
#include "Atom.h"
#include "CoreDotNet.h"
namespace CoreWrapperNS
{
    public ref class AtomDotNet
    {
    private:
        Atom*       _atom;
        CoreDotNet^ _core;
    public:
        AtomDotNet()
        {
            // The atom allows users to instantiate an atom with a core
            // and to get a reference to the core of the given atom.
            Core* core = new Core();
            _atom = new Atom(core);
            _core = gcnew CoreDotNet(core);
        }
        inline CoreDotNet^ GetCore(){return _core;}
        //... destructor follows
    };
}

CoreWrapper项目有一个对CoreLib项目的引用。我在"互联网"上看到过一些关于CLI/c++包装器得到上述编译器错误的帖子,因为它们引用了c++项目并且它们包括头文件,但我没有这个问题,直到我添加了第二个类(即AtomDotNet类)到包装器库,我试图编译它。你知道这里会发生什么吗?

仅仅在头文件中编写代码并不会导致它被包含在项目中。

您需要将.cpp文件添加到项目中,并将#include添加到头文件中。

c++/CLI不需要头文件,事实上c++/CLI声明的优点之一是它不需要头文件,而使用反射来获得它需要的信息,这些信息通常包含在头文件中。把你的。h重命名为。cpp,忘掉。h,除非在本地代码中。

要使用在同一项目中的另一个.CPP文件中定义的托管类,请对CoreDotNet.cpp中的obj文件使用'#using'(类似于#include),如下所示:

#using "AtomDotNet.obj"

另外,在您的CoreDotNet.cpp属性页或在您的项目属性中,在C/c++下的Resolve #使用参考添加"$(IntDir)"路径,以便它可以在编译时找到文件。

这是c++/CLI的方式,没有更多的DLL地狱和。h地狱!

c++/CLI没有头文件的概念。头文件中的声明就是它的实现。因此,在"AtomDotNet.h"中包含"CoreDotNet.h"就是问题所在。

如果你的CoreDotNet.cpp只包含:

#include "CoreDotNet.h"

和"AtomDotNet.h"的类似模式,然后从"AtomDotNet.h"中删除"CoreDotNet.h"包含,您应该能够编译它。

你需要像对待c#项目和相关类/*.cs文件一样对待c++/CLI。