Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle C# - C++ project interaction the right way?

Tags:

c++

c#

dll

I´m really in the need of getting a deeper understanding of how to set up things right to get an elegant interaction between my C++ and C# code bases. What I want to achieve is an in-game editor written in C# for my game engine (C++/DX). For doing so I let VS build my engine as a C++ dll with some additional functions (unmanaged code) to access the required functionality of my engine from the C# editor code base. So far so good.

The first thing which is bugging me is that I´ve to build the dll with CLR support. Otherwise C# does not accept the dll for some reason. It doesn´t even allow me to add it to the resources ("A reference to 'C:\Users...\frame_work\Test\frame_workd.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.").

And when I build the dll with CLR support and add it to the references in C# ,re-build without CLR support, start my editor and make a function call from the dll then I get an Exception HRESULT: 0x8007007E. I searched for it but the only thing I found had to do with dependencies but that doesn´t fit to the alert I get when adding the dll to the resources.

The other point is that I always have to switch the configuration type between application (.exe) and dll. in VS C++ depending on whether I want to run my engine directly or from the editor and every time the complete project is build completely new.

So, could someone explain to me how to organize this the right way? And what could be a possible reason why C# wants the dll to be compiled with CLR support?

Thank you guys/girls.

like image 817
user1042568 Avatar asked Oct 24 '22 19:10

user1042568


2 Answers

There are two ways to deal with this.

Either you make your C++ code provide an API which has a fully compliant COM object. If the object is COM then C# can directly interop with it. (This is why you can't add it as a reference directly)

However I think what you are really wanting to do will involve a P/Invoke (calling C/C++ native code from C#). This is entirely possible but it's not always easy. You need to deal with conversions between your C++ API and your C#, pointers and you need to be very careful to pin any references that your C++ code writes to in the C# app.

like image 74
Spence Avatar answered Nov 01 '22 11:11

Spence


C# code is managed code (runs in the CLR), and can only directly* reference managed assemblies. So of course you're getting an error when you build against a managed assembly, and then sneak in and replace that managed DLL with an (incompatible) unmanaged DLL. You're basically trying to lie to the compiler, and that generally doesn't end well.

If you want your C++ DLL to be accessible from C#, the simplest way to do it is to build it as a managed assembly (i.e., CLR support). Which you're already doing. Just take out the extra step where you replace the working managed DLL with a non-working unmanaged one.

Also:

C++ dll with some additional functions (unmanaged code) to access the required functionality of my engine from the C# editor

That won't help you, because C# can't directly* call unmanaged code. The simplest way to make this work will be to make additional managed classes and methods in your C++ DLL. Then your C# assembly will be able to directly use those managed classes.

* As Spence noted, you can use -indirect- means (P/Invoke and COM) to access unmanaged code from C#. But that will make your life much more complicated than it is now, not to mention how it will complicate your build and deployment. You're already really close to something that should work -- don't add all that extra complexity.

like image 33
Joe White Avatar answered Nov 01 '22 10:11

Joe White