首页 > 解决方案 > 在 C# 托管类的方法中,如何传递 C++ 类的实例?

问题描述

我正在做一个联合项目,需要包装一个 C++ DLL 并从 C# 中引用它。

我不是来自 Microsoft 技术背景,所以如果我的术语不正确,或者这最终是一个简单的回答或已经回答的回答,我深表歉意 - 但尽管搜索得很好,但我肯定找不到那个答案。

到目前为止,另一方已经完成了将相关 DLL 转换为托管 DLL 的工作。这使我可以将它作为参考包含在我的 C# 项目中(我使用的是 VS 2017)。对方还给我发了一个如何提供包装器的C#示例(仅实现了一个方法'Clear'),如下:

#pragma once
#include "cgcl.h"

using namespace System;
using namespace ThirdParty_DOPRL;

namespace ThirdParty_GCL 
  {
    public ref class CGCL_MAN
      {
        public:
            // Allocate the native object on the C++ Heap via a constructor
            CGCL_MAN() : m_pGCL( new CGCL ) {}

            // Deallocate the native object on a destructor
            ~CGCL_MAN() {
              delete m_pGCL;
            }

        protected:
            // Deallocate the native object on the finalizer just in case no destructor is called
            !CGCL_MAN() {
                delete m_pGCL;
            }

        public:
            void Clear() {
                return m_pGCL->Clear();
            }

        private:
            CGCL * m_pGCL;
      };
  }

到目前为止,所有构建都正常并且工作正常(即从 C# 对 Clear() 的调用似乎可以执行)。

我现在想为与上面相同的非托管类中的另一个方法添加存根。它在原始头文件中的签名如下:

  STATUS GetListOfDevProperties(CDeviceObjectPropertyReferenceList &DevicePropertyList) const;

所以我做的第一件事就是围绕非托管类 CDeviceObjectPropertyReferenceList 创建另一个包装类,如下所示:

#pragma once

#include "cdoprl.h"

using namespace System;

namespace ThirdParty_DOPRL
{
    public ref class CDOPRL_MAN
    {
    public:
        // Allocate the native object on the C++ Heap via a constructor
        CDOPRL_MAN() : m_pDevObjPropRefList(new CDeviceObjectPropertyReferenceList) {}

        // Deallocate the native object on a destructor
        ~CDOPRL_MAN() {
            delete m_pDevObjPropRefList;
        }

    protected:
        // Deallocate the native object on the finalizer just in case no destructor is called
        !CDOPRL_MAN() {
            delete m_pDevObjPropRefList;
        }

    public:
        bool IsEmpty() {
            return m_pDevObjPropRefList->empty();
        }

        void Clear() {
            return m_pDevObjPropRefList->clear();
        }

        size_t Size() {
            return m_pDevObjPropRefList->size();
        }

    private:
        CDeviceObjectPropertyReferenceList * m_pDevObjPropRefList;
    };
}

现在回到 ThirdParty_GCL(在这篇文章的顶部),我假设我必须在存根中使用托管类类型,并声明存根如下:

            STATUS GetListOfDevProperties(CDOPRL_MAN devPropList) {
                return m_pGCL->GetListOfDevProperties(devPropList);
            }

但是,当然,VS 警告我在上面的 return 语句中提到 devPropList 是无效的(“一个简单的非跟踪引用不能绑定到托管堆上的实体”)——对我来说,简单来说,这意味着我非法混合对非托管类和托管类的引用。

简而言之,有没有办法在托管 CDOPRL_MAN 类类型和原始 C++ DLL 所需的非托管 CDeviceObjectPropertyReferenceList 类类型之间进行转换?

希望我提供了足够的信息。

标签: c#c++unmanagedmanaged

解决方案


推荐阅读