传递非托管 C++对象到托管 C++代码

发布于 2024-12-17 21:16:46 字数 2194 浏览 0 评论 0原文

因此,正如标题所述,我希望将非托管 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;

该对象是一个类, 希望能够通过仅传递对象来从我的托管代码中访问外部对象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

有什么想法吗?

So as the title states, I am looking to pass an object that is defined in an unmanaged C++ project into a managed C++/CLI project (both projects are in the same solution) while still being able to access the same methods as in the unmanaged C++ project.

This object is a class which imports functions from a separate unmanaged C++ dll (not in the same project or solution) through the means of using typedef's as shown below (excerpt of header):

#pragma unmanaged    

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

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

    someBoolFunc BoolFunc;
}; 

extern INeedThisClass ReallyNeedThisClass;

I would really like to be able to access the externed object ReallyNeedThisClass from within my managed code by just only passing the object. By having this object I wish to access it's methods through ReallyNeedThisClass->BoolFunc. What is the best way of accessing this object from my managed code?

EDIT: I've been thinking maybe there is a way of using a property to "Get" the object from the unmanaged code and then "Set" the same object in the managed code. Could this be a proper angle to approach this issue from? I've cleaned up the question a bit to get rid of useless details.

UPDATE: I've made progress on this using a wrapper for the unmanaged C++ code, but of course there are still problems. Using the above class as an example here, I will show you what I have managed to do up until now.

Project 1: Unmanaged C++ class (example above)

Project 2: Managed C++/CLR wrapper class (example below)

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

Now I am receiving errors from the compiler stating:

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

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉城凉梦凉人心 2024-12-24 21:16:46

首先,您必须从非托管 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;
};

此外,非托管 dll 必须使用 UNMANAGED_COMPILE_DEFINITION 预处理器定义进行编译。

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

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

第四,我不记得了,但如果您包括“Windows.h”或“Winnt.h”,有关WINAPI的错误将消失。

First, you have to export INeedThisClass from unmanaged dll and import from managed one.

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

Also unmanaged dll must be compiled with UNMANAGED_COMPILE_DEFINITION preprocessor definiton.

Second, remove extern INeedThisClass ReallyNeedThisClass; you don't need it. Because ReallyNeedThisClass is a member of wrapper class already.

Third, you need to marshal System::String^ to TCHAR* in order to call BoolFunc

Forth, I do not remember but if you include "Windows.h" or "Winnt.h", the error about WINAPI will be gone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文