Reputation: 83
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 extern
ed 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?
Upvotes: 3
Views: 3014
Reputation: 4873
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.
Upvotes: 3