I have an interface that I have defined in C++ which now needs to be implemented in C#. What is the best way to go about this? I don't want to use COM at all in my interface definition. The way I have solved this right now is to to have two interface definitions, one in C++ and one in C#. I then expose the C# interfaces as a COM server. This was my application which is written in C++ can call into C#. Is there anyway I can avoid having to define my implementation in C++ as well as C#?
Why don't you want to use COM?
This would have been my suggestion. COM interop has worked really well for me, and I've used COM objects and interfaces in C# (simply reference the COM object and the runtime callable wrapper gets created automatically). Similarly marking a C# class as "Register for COM interop" has worked the other way around.
Thanks for the answer.
Can't use COM since the interface needs to be implemented in both the *nix world and Windows world.
If you are willing to use C++/CLI for your managed code instead of C#, then you can just consume the native C++ interface definition directly via the header file. How easy this will be will depend on exactly what is in your interface - simplest case is something that you could use from C.
Take a look at Marcus Heege's Expert C++/CLI: .NET for Visual C++ Programmers, for a lot of helpful information on mixing native and managed C++ in .NET.
Write the interface in C++ and use macros to make it look like a standard cpp header file on UNIX and like an IDL file on windows (If this does not work out, you can always write a python/ruby script to generate the IDL from the C++ header file).
Compile the IDL to generate a typelib. Use TypeLib Importer to generate the interface definitions for C# and implement the interfaces there.
Write the interface in IDL and use a tool to compile the interface to the target language. You might find pointers for this when looking into CORBA which was concerned with cross-language interfacing.
/Allan
You don't mention which version of .NET you're using, but something that's worked for me in using Visual Studio .NET 2003 is to provide a thin C# wrapper around the pimpled implementation of the real C++ class:
public __gc class MyClass_Net {
public:
MyClass_Net()
:native_ptr_(new MyClass())
{
}
~MyClass_Net()
{
delete native_ptr_;
}
private:
MyClass __nogc *native_ptr_;
};
Obviously, one would prefer to use a Boost shared_ptr there, but I could never get them to play nicely with V.NET 2003...
Methods simply forward to the underlying C++ methods through the pointer. Method arguments may have to be converted. For example, to call a C++ method which takes a string, the C# method should probably take a System.String (System::String in Managed C++). You'd have to use System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi() to do that.
One nice thing about this approach is because Managed C++ is a .NET language, you get to expose accessors as properties (__property). You can even expose attributes, very much like in C#.
The other approach is to use a 'flat', C-style API. You might as well use extern "C"
to prevent accidental overloading. Use a DEF file to explicitly name the exported functions, so they're definitely not decorated in any way (C++ functions are 'decorated' with an encoding of the parameter types in the export table).
On x86, beware of calling conventions. It's probably to explicitly declare the use of __stdcall
or __cdecl
. Because P/Invoke is primarily used to invoke Windows APIs, it defaults to StdCall, but C and C++ default to cdecl, because that supports varargs.
I recently wrapped the COM interface IRapiStream
in a flat C interface as .NET seemed to be trying to convert the IStream into a storage, which failed with the error STG_E_UNIMPLEMENTEDFUNCTION
.