【问题标题】:Passing unmanaged C++ object into managed C++ code将非托管 C++ 对象传递给托管 C++ 代码
【发布时间】:2011-11-24 17:09:06
【问题描述】:

因此,正如标题所述,我希望将在非托管 C++ 项目中定义的对象传递到托管 C++/CLI 项目(两个项目在同一个解决方案中),同时仍然能够访问与在非托管 C++ 项目中。

此对象是一个类,它通过使用typedef 的方式从单独的非托管 C++ dll(不在同一个项目或解决方案中)导入函数,如下所示(标题摘录):

#pragma unmanaged    

typedef BOOL (WINAPI *someBoolFunc) (DWORD Name, DWORD Flags, TCHAR* Text);

class INeedThisClass
{
public:
    INeedThisClass();
    ~INeedThisClass();

    someBoolFunc BoolFunc;
}; 

extern INeedThisClass ReallyNeedThisClass;

我真的希望能够通过仅传递对象从我的托管代码中访问externed 对象ReallyNeedThisClass。通过拥有这个对象,我希望通过ReallyNeedThisClass->BoolFunc 访问它的方法。从我的托管代码访问此对象的最佳方法是什么?

编辑:我一直在想,也许有一种方法可以使用属性从非托管代码中“获取”对象,然后在托管代码中“设置”相同的对象。这可能是一个合适的角度来解决这个问题吗?我已经清理了一些问题以摆脱无用的细节。

更新:我使用非托管 C++ 代码的包装器在这方面取得了进展,但当然仍然存在问题。在这里以上面的class 为例,我将向您展示我到目前为止所做的工作。

项目 1:非托管 C++ 类(上例)

项目 2:托管 C++/CLR 包装类(示例如下)

Wrapper.h

#pragma once

#include "INeedThisClass.h" //Unmanaged class INeedThisClass

using namespace System;
using namespace System::Runtime::InteropServices;

namespace INeedThisClassWrapper
{
    public ref class INTC
    {
    public:
        INTC(void);
        virtual ~INTC(void);

        delegate bool BoolFunc(UInt32 Name, UInt32 Flags, String^ Text);

    private:
        INeedThisClass *ReallyNeedThisClass;
    };
}

Wrapper.cpp

#include "Stdafx.h"
#include "Wrapper.h"
using namespace INeedThisClassWrapper

#include <msclr/marshal.h>
using namespace msclr::interop;

INTC::INTC(void)
{
    ReallyNeedThisClass = new INeedThisClass();
}

INTC::~INTC(void)
{
    if (ReallyNeedThisClass)
    {
        delete ReallyNeedThisClass;
        ReallyNeedThisClass = NULL;
    }
}

bool INTC::BoolFunc(UInt32 Name, UInt32 Flags, String^ Text)
{
    return ReallyNeedThisClass->BoolFunc;
}

现在我收到来自编译器的错误说明:

error C2065: 'WINAPI': undeclared identifier
error C2065: 'someBoolFunc': undeclared identifier
error C4430: missing type specifier - int assumed. Note C++ does not support default-int

有什么想法吗?

【问题讨论】:

  • 在人们开始声称这可能是一个重复的问题之前...我查看了在此问题之前发布的其他问题,但没有一个对这种情况有真正用途的答案(如果他们有答案的话)。
  • 您下次可以添加这些问题的链接,帮助回答者检查他们的灵感。
  • 答案取决于您要使用的库类型。你看过codeproject.com/KB/mcpp/usingcppdll.aspx吗(你通过谷歌搜索“在托管C++中使用非托管dll中的代码”找到)
  • 在发布我的问题之前,我确实看过这个。由于他们导出类的方式,这篇文章让我有点困惑。我真的不应该玩弄我想要访问的类的代码。我宁愿不必更改将函数导入到未管理类的方式,因为还有其他类取决于现在类的编写方式。如果使用我在问题中使用的方式实现该类,您知道这种方法(使用typedef BOOL WINAPI)是否仍然有效?

标签: c++ object c++-cli unmanaged managed


【解决方案1】:

首先,您必须从非托管 dll 中导出 INeedThisClass,然后从托管 dll 中导入。

//unmanaged header

#if UNMANAGED_COMPILE_DEFINITION
#define EXPORT_OR_IMPORT __declspec(dllexport)
#else
#define EXPORT_OR_IMPORT __declspec(dllimport)
#endif

class EXPORT_OR_IMPORT INeedThisClass
{
public:
    INeedThisClass();
    ~INeedThisClass();

    someBoolFunc BoolFunc;
};

还必须使用 UNMANAGED_COMPILE_DEFINITION 预处理器定义编译非托管 dll。

其次,删除你不需要的extern INeedThisClass ReallyNeedThisClass;。因为ReallyNeedThisClass 已经是包装类的成员了。

第三,您需要将System::String^ 编组为TCHAR* 才能调用BoolFunc

第四,我不记得了,但如果你包含“Windows.h”或“Winnt.h”,关于WINAPI的错误就会消失。

【讨论】:

猜你喜欢
  • 2011-02-27
  • 1970-01-01
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多