New technologies are always replacing existing ones. A common transition
right now is from C++ to C#. Microsoft helped this transition greatly
by creating the managed extensions to C++, which essentially gives us
access to all things .NET.
Interfaces are not a language feature of native C++. There are several
mechanisms for replicating the functionality, but it's not built in.
Interfaces in C#, however, are ingrained directly in the language and
are a important construct for any reasonably complicated architecture.
That being said, in order to move forward with new C# code, the C++ is
going to have to support interfaces, which is why Microsoft added that
feature to C++'s managed extensions.
I'm going to assume you've already got a project you're working with,
but for the purposes of this tutorial, I've created a default Visual C++
class library and a C# class library and added both of them to the same
solution. Here's a screenshot of my solution explorer in Visual Studio.
Let's start with the C# interface definition. I've created a very basic
interface to get us started.
public interface MyInterface
{
int InterfaceMethodOne();
string InterfaceMethodTwo();
}
In order to expose this interface to the C++ project, we're going to
have to add the C# project as a reference. Simply right mouse click on
the C++ project and select "References". Once in there select "Add New
Reference..." then choose the "Projects" tab and select the C# project.
By default, this is what Visual Studio generated when the C++ project
was created.
// ManagedCPPApp.h
#pragma once
using namespace System;
namespace ManagedCPPApp {
public ref class Class1
{
// TODO: Add your methods for this class here.
};
}
The changes required to implement the interface are pretty minor.
// ManagedCPPApp.h
#pragma once
using namespace System;
namespace ManagedCPPApp {
public ref class Class1 : public CSharpLib::MyInterface
{
public:
virtual int InterfaceMethodOne() { return 0; };
virtual System::String^ InterfaceMethodTwo() {return ""; };
};
}
The first thing you might notice is that this is a
ref
class. Native
C++ classes cannot implement managed interfaces. The syntax to implement
the interface is identical to how C++ does inheritance - just stick the
name after the colon.
Now you'll need to create definitions for each function in the
interface. This is really straight forward, except the
virtual
keyword
is required in the method signature (I can't tell you how many times
that stumped me).
I guess the only other oddity is the carat at the end of
System::String^
. This is simply the managed C++ way of representing a
reference. Since in C#, strings are returned by reference, you'll need
to represent that in the C++. In my own opinion, I think the managed C++
syntax is really strange.
And that's it. You've implemented a basic interface. Now let's throw
something in the interface that's a little more difficult - properties.
public interface MyInterface
{
float InterfacePropertyOne { get; set; }
int InterfaceMethodOne();
string InterfaceMethodTwo();
}
Implementing properties in managed C++ is fairly similar to C#. Here's
the new C++ implementation of the interface.
public ref class Class1 : public CSharpLib::MyInterface
{
public:
virtual int InterfaceMethodOne() { return 0; };
virtual System::String^ InterfaceMethodTwo() {return ""; };
virtual property float InterfacePropertyOne
{
void set(float value) { };
float get() { return 0; };
};
};
All that's really left now are events. The syntax between C# and C++
for implementing events are nearly identical.
public interface MyInterface
{
event EventHandler InterfaceEventOne;
float InterfacePropertyOne { get; set; }
int InterfaceMethodOne();
string InterfaceMethodTwo();
}
And here's the C++ implementation:
public ref class Class1 : public CSharpLib::MyInterface
{
public:
virtual event System::EventHandler^ InterfaceEventOne;
virtual int InterfaceMethodOne() { return 0; };
virtual System::String^ InterfaceMethodTwo() {return ""; };
virtual property float InterfacePropertyOne
{
void set(float value) { };
float get() { return 0; };
};
};
There we have it. We've defined an interface in C# that we've
implemented in C++. All-in-all the process is not that difficult, it's
just a matter of wrapping your head around the crazy syntax in the
managed extensions for C++.
Comments
Post a Comment