Is it a good idea to combine C++ and C# or does it pose any immediate issues?
I have an application that needs some parts to be C++, and some parts to be C# (for increased efficiency). What would be the best way to achieve using a native C++ dll in C#?
Yes using C# and C++ for your product is very common and a good idea.
Sometimes you can use managed C++, in which case you can use your managed C++ module just like any other .NET module.
Typically you'd do everything that you can in C#. For the parts you need to do in C++ you'd typically create a C++ DLL and then call into that DLL from C#. Marshalling of parameters is done automatically for you.
Here is an example of importing a C function inside a DLL into C#:
[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);
The question is clearly how to integrate his own C++ code to his C# solution, not just what attribute to use in order to call an existing function from the win32 API. Even if the answer was already accepted, I think it's incomplete, and the following should apply.
Yes, it is common practice in the cases where the task can either run faster, use less resources, and also in some cases to access methods that are not available in the .net framework.
If your goal is to gain efficiency you need to code a native unmanaged C++ library, you will create a new unmanaged c++ project(that compiles as a dll library) in visual studio and reference this library from your C# project.
In your case it seems you might be writting an unmananged C++ library, and the following applies.
As for any immediate issues you were asking about, it would impact deployment and obfuscation.
Deployment: Keep in mind that the C# dlls you build will run on any cpu, both 32 and 64bit, but this new native and unmanaged C++ library will force your program to be either for 32 or 64 specific.
This is something you will configure in your Visual Studio configuration manager, and will be taken care of at compile time, you will pick AnyCPU for C# assemblies and for your new unmanaged C++ library, which will be in it's own project, you will have to choose from win32 or x64.
So you will now have 2 setups, it is recommended best practice to have separate setups, one for 32 and another one for 64. Or since 32bit support is dropping very fast, you could focus on 64bit only.
Also, your library might end up referencing the VC++ redistibutable provided by visual studio, which you might have to include in your deployment, altho some version of it are included on many OS, I found it's rarely the same one I compiled with and it's best to deploy it with your application to be sure. If this pack is missing, the target machine will have a SideBySide exception in the eventviewer->application log.
To catch and handle an exception thrown from unmanaged code, the only catch that works is the empty one, the one with no exception type in the parenthesis after the catch(). So you can wrap your calls to unmanaged code in this to handle all unmanaged exception thrown from inside the unmanaged code, if you put a .net type like catch(Exception), it will just jump over it. The only way to catch an unmanaged exception, inside managed code is in this format.
//call unmanaged code
//handle unmanaged exception
- Obfuscation: Any method calls done from C# that are now calling unmanaged code will now be excluded from renaming automatically. And on the flip side, if your unmanadged c++ library needs to call methods from your managed assemblies, those will need to be excluded from renaming, manually, in order to be visible to the C++ library calling them.
If what you need is only to call well known c++ libraries like the Windows ones, you will NOT need to create a new unmanged c++ project, only use the [DllImport()] attribute suggested in a previous answer. And in this case you could take a look at this reference http://www.pinvoke.net/
What about C++ .NET? You can write managed code as well as native c++ code.