Передача неуправляемого объекта C ++ в управляемый код C ++ - PullRequest
3 голосов
/ 24 ноября 2011

Итак, как гласит заголовок, я собираюсь передать объект, который определен в неуправляемом проекте C ++, в управляемый проект C ++ / CLI (оба проекта находятся в одном и том же решении), но при этом иметь возможность доступа к тем же методам, что и в неуправляемом проекте C ++.

Этот объект является классом, который импортирует функции из отдельной неуправляемой dll C ++ (не в том же проекте или решении) посредством использования typedef, как показано ниже (выдержка из заголовка):

#pragma unmanaged    

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

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

    someBoolFunc BoolFunc;
}; 

extern INeedThisClass ReallyNeedThisClass;

Мне бы очень хотелось иметь возможность получить доступ к extern ed объекту 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

Есть идеи?

1 Ответ

3 голосов
/ 28 ноября 2011

Сначала вы должны экспортировать 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 INeedThisClass ReallyNeedThisClass;, вам это не нужно. Потому что ReallyNeedThisClass уже является членом класса-оболочки.

В-третьих, вам нужно набрать System::String^ до TCHAR*, чтобы позвонить BoolFunc

Далее, я не помню, но если вы включите «Windows.h» или «Winnt.h», ошибка о WINAPI исчезнет.

...