Why does a multilanguage solution not work? - c#

My solution has a
C# application project
C# User Controls project
C++ Mathematics project
One of the UserControls uses function from the Mathematics (C++ project). This UserControl is used in the application.
Building and starting the application works just fine. When typing the IntelliSense suggests all the contained classes and methods. The UserControl appears correctly, but on clicking a button which calls the C++ function I get a BadImageFormatException (it pops out on the end of the automatically created Main function).
The help suggests to use /fixed:no for linking, but that is already set up.

You can get BadImageFormatException when running a 32bit dll on a 64bit system. Try setting the target to "x86" on all your projects.

Based on the information you are giving, it sounds like the managed code is trying to call into the C++ DLL as if it were managed code (and it is maybe built as unmanaged code). The information about BadImageFormatException discusses this:
An attempt is made to load an unmanaged dynamic link library or executable (such as a Windows system DLL) as if it were a .NET Framework assembly.
If you are building the C++ project as unmanaged code, you may need to use p/invoke to call into it.

Related

Visual Studio mixed projects debugging

I have a solution primarily based on C# projects, but I will occasionally need to use libraries written in native c++. The way I have solved this is by having a native project that simply acts as a wrapper for a native library, in this case OpenCV (I know I could use EMGUCV directly in C#, but in my experience it has some bugs that I would like to avoid and this is more a proof of concept anyways). I then have a C++ CLR project that references the native wrapper, and finally a C# project referencing the C++ CLR project. Strictly speaking I could just reference OpenCV directly from the CLR project instead of having the native wrapper project, but I would like to organize it this way both to conform to how the rest of the solution is organized and because I might at some point want to have this structure for another reason.
The first problem with this approach is that I can't find a way for Visual Studio to automatically include the dll of the native wrapper in the final target directory. Referencing the native project from the CLR project works flawlessly and referencing the CLR project from the C# project is no problem, but when I build it won't run because the native dlls are not brought to the final target. I solved this by adding some post build actions to copy the native dll and pdb files. This works, and I'm able to run the code with no errors. However, I'm unable to debug the native project. I hit breakpoints in the C# project and CLR projects, but not the native project.
What I have tried:
In the C# project properties I have enabled the native code debugging option.
In the CLR project I have set debugging mode to mixed.
In the native project I have tried both native only and mixed debugging mode
In the C# project I have checked allow unsafe code
In visual studio under tools->options->debugging->general I have tried checking and unchecking use native compatibility mode and suppress jit optimization on module load.
I tried opening the native project in a separate visual studio instance to attach the debugger to the project running from the whole solution, but I was not allowed to do this as the solution debugger was already attached to that project. Someone suggested to do this, but didn't explain how this could be done.
The problem was that the C# project I referred to before was in itself a dll being called by another C# exe project. When I enabled native debugging for this project, everything worked as expected.

Build and deliver a C/C++ DLL into a C# app using Visual Studio 2013

I am a Visual Studio 2013 Newbie who is trying to figure out how to build a C DLL in Visual Studio and then invoke the functions exported by the C lib from within a C# app. I've got everything building, but I cannot figure out the proper way of getting the DLL included with the app build so that it will actually load properly when using [DLLImport()]. I currently get a System.DllNotFoundException when attempting to invoke a function from the library from within my C# class.
I have setup a VS 2013 solution which contains the following projects:
HelloWorldLib.Shared :
Shared project that contains the .cpp and .h files for the DLL
HelloWorldLib.Windows :
Win 8.1 C++ project that references the shared project and builds the DLL for Win 8.1
MyApp-Win.Windows :
C# project for Win 8.1 that wants to make use of the HelloWorldLib.Windows.dll produced by the HelloWorldLib.windows build
I have been looking over many SO questions and answers. For instance, I think my question is similar to this one, which doesn't appear to have been answered in any useful way:
Interop, Native DLL and Visual Studio build process
Some of the other answers suggested adding a file reference to the DLL, but how would I do that and keep the proper Debug/Release versions? Given that all of these projects are being built within the same solution, and there are build dependencies between them, it feels like there should be a straightforward way to set this up.
BTW, I am using the shared project setups, as my ultimate goal is to figure out how to get this all working with Xamarin to target iOS, Win, Win Phone, Mac and Android. So that we can use a common C/C++ layer for our high performance requirement code, and the reference it from the UI layers on the various platforms.
This is a pretty straight-forward problem, easy to identify if you look where the built files end up. The C++ build system has a different strategy than the managed build system. It by default writes the build output to the solution directory's Debug directory. Your C# project however builds to its bin\Debug directory and requires all dependent DLLs to be present there.
So, by default, your C# program can never find the DLL, it is in the wrong directory and Windows doesn't look there. Nor is MSBuild smart enough to discover this by itself, like it can for managed DLLs, it cannot see that you program depends on the C++ DLL.
Two basic ways to work around this:
Change the C++ project's Output Directory setting
Write a post-build event for your C# project that uses xcopy.exe to copy the DLL.
Unfortunately things aren't that easy, at least not yet. I was going to have a meeting with Microsoft C++ team but that got postponed, similar functionality you are after was one of the things on my wishlist (building managed C++/CLI wrappers for Xamarin.iOS and Android).
Currently, if you can, the easiest option is to wrap C++ code inside a DLL that exposes C interface. Then build it with XCode and Android NDK. If you can't then the next option is to create Objective-C binding project that wraps the C++ code inside Objective C classes for iOS. For Android either create Java wrapper or use SWIG. Both of these options are cumbersome which is why C API should be the first choice you investigate.
I know it's not the answer you were hoping for but reusing C++ code is way more complicated than reusing C# or even C.

C# Code in C++ Project

I've read many solutions to the issue of using C# code in a C++ project, including this one: How to use c# code in C++ project
I've also read this, and one answerer says Compile your C++ code with the /clr flag. With that, you can call into any .NET code with relative ease.
Does this mean that I can use C++ & C# code together, within the same project if I append the /clr flag?
I'm a little confused by this, and it'll just waste time if I went the long route of converting the C# project that I'm trying to use parts of to C++, if doing so isn't actually needed.
Basically, I answered my own question on a different topic a couple of days ago without realising that the actual code of the sample project is C#:
Obtaining Current Network Rate
Can anybody give me a firm clarification to whether I understand this correctly (that I can use C# code in a C++ project with no issues, apart from the /clr switch being required)?
I'm not sure if SO is the right place to ask a question like this, so please tell me if it isn't instead of downvoting with no explanation.
Thanks.
Edit
Forgot to mention that this is a C++/CLI gameserver application DLL on Windows. If it matters, it is used on only Windows Server 2008 R2 and Windows 7.
If you use C++/CLI, then you can add references to other .net assemblies, but you do not mix C++ and C# code in the same project. What you would do is to create a new project (or add an existing one) in your solution using C#, and then add a reference to it in the C++/CLI project.
The drawback is that you need to marshal between C++ and .Net types (std::string vs System::String^), and you also need to learn the additional syntax used by C++/CLI (^, gcnew, etc.).
Further reading: Pure C++: Hello, C++/CLI
It means, that with the /clr switch, you can access assemblies (DLL or EXE) written for the .Net framework. Because such assemblies can be created with any .net language (including C#), you can use "code" written in C# from within C++, but it doesn't mean that you would be able to write C# in C++ project. Unfortunately - you can't.
You need to make a C++/CLI project in visual studio.
C++/CLI is a bit different to C++, because there is the managed stack, so memory is managed and you can avoid memory leaks (garbage collection).
Simply create a C++/CLI project and click on propietys and add a reference to your C# project, it should work :D
http://www.codeproject.com/KB/cs/ManagedCOM.aspx

Making a c# winforms application useable as a dll from an unmanaged mfc application

I'm wondering how I would go about converting an existing c# winforms application to a class library and then call it from an mfc application. Are there any references on how to do this? I've tried googling, but, besides the fact that it will need the ComVisible attribute set to true I haven't found much information.
Thanks.
In visual studio project properties change the output type to class library. This will make your project compile into a dll. Also set the comvisible attribute to true. Thus will generate a com callable wrapper and a tlb file which you can use from your mfc project.
Also I think the following link is a very good and detailed explanation of how COM Interop works in .Net
http://www.codeproject.com/KB/COM/cominterop.aspx
Have a look at the regasm.exe tool shipped with .NET. It will generate the necessary registry entries (and optionally a .tlb file) that will allow COM components to access your assembly.
There is an MSDN sample that covers putting a Winforms user control on an MFC app - dialog or view. In addiition to code this should show you the project settings you will need.
Once you get this build properly, then you will need to get it to run properly. The main problem might be correctly parenting the windows forms from unmanaged windows, basically getting your managed forms to live inside what started as an unmanaged application. If you don't use WPF as the UI bridge between your unmanaged code and managed forms, then you will need to do this work yourself. You can google this topic for more info, don't have a link for this handy at the moment.

Adding dlls in VS 2008

I would like to add some external .dll libraries e.g. glut32.dll (but it's only example) in Visual Studio 2008, using C#.
Can you please tell me what should I do step by step?
I am a little bit confused cause I found a lot of solutions to add dll files, but they significantly differ.
Some of them add dll's only using code, some using properties in vs, add references and in other tutorials there is about registering dlls in system.
But how to put it all together?
There are different kinds of DLLs, you'll need to treat them differently when you use them in a C# project. The 3 main kinds are:
DLLs that contain unmanaged code and were designed to be used by a program written in unmanaged code. You cannot use such a DLL directly, there is no way to add a reference to them in a C# project. You must use P/Invoke, the [DllImport] attribute is required to declare the exported functions in the DLL. Glut32.dll is such a DLL. A very basic test you can use to see if you've got such a DLL is to run Dumpbin.exe /exports on that DLL. It lists the names of the functions that are exported.
DLLs that implement an in-process COM server. They are written in unmanaged code as well. .NET has very good support for using such servers, as long as you have a type library for them. The type library is usually embedded in the DLL, Visual Studio expects to find it when you add a project reference, either through the COM tab or the Browse tab. A very basic test is Dumpbin.exe /exports again, an in-process COM server has 4 exported functions. The DllGetClassObject function is the important one. You can view the type library embedded in the DLL with OleView.exe, File + View Typelibrary. A good example is c:\windows\system32\shell32.dll
DLLs that were created by a managed compiler. They don't contain machine code like the other types, they contain IL code and metadata. It is the native kind of DLL for managed code, you simply use Project + Add Reference to add a reference, the compiler automatically knows the types that are available in the DLL.
The first kind is the one you'll encounter a lot for DLLs in the wild. There's a lot of code written for Windows in an unmanaged language. It isn't a kind of DLL that's particularly easy to use from managed code. Glut32.dll for example has a lot of exported functions, writing a P/Invoke declaration for every single one of them is painful.
Tools you can use to help with this are SWIG and PInvoke Interop Assistant. The former is required when the DLL was written in the C++ language. C++ classes are not directly usable from a C# program, they need a wrapper written in the C++/CLI language. The latter tool is useful for DLLs written in C, including the Windows API.
Beware that those tools don't usually give you a clean and guaranteed-to-work interop solution. Declarations in unmanaged code are ambiguous, you'll need to know the exact semantics of the arguments of an unmanaged function to pick the right one. Getting the wrong one can be hard to diagnose, the best place to get help is a forum or Q+A site. Like stackoverflow.com
You can use the add reference dialog under the project menu to do that. Just go to the COM tab and add your library. Now you can verify that the classes appear in teh object browser
Right click on project in solution explorer and select add reference and then browse and select the dll.
If you wish to reference the dlls you
Right Click on References, and select add reference.
Or have a look at
How to: Add and Remove References in Visual Studio (C#)
Adding a Reference to a C# or Visual Basic .NET Project
In Solution Explorer, right-click the project node and click Add Reference.
In the Add Reference dialog box, select the tab indicating the type of component you want to reference.
Select the components you want to reference, and then click OK. Tip.

Categories

Resources