I don't know why but today myOpenID doesn't seem to work. Anyway ... I have this problem: I have a unmanaged C++ library (DLL) which I have to embed in an existing C# project. Now ... I have created a mini-wrapper (DLL) in managed C++ which calls the library so that I can load it from the C# code and, when I try it from a command-line C# project, it perfectly works, right results, right behavior ecc.
Now, when I load it in the real project, it starts giving me strange System.AccessViolationException coming from the mini-wrapper DLL. I am not experienced in C#, nor in general manged/unmanaged C++ development under Windows, and I just can't understand why should this work from a C# project, and not work from another.
More information: the original library uses OGRE3D rendering engine to do calculations, and the project in which I have to use this library uses OGRE under the hood, could this cause problems?
Any suggestions?
Here are some ideas for you to try sir...
It's hard to know whats going on exactly but the first thing I would try to do is remove this managed c++ dll from the mix. It might be confusing things. Somewhere here this feels like data is not being marshalled correctly between the managed and unmanaged world. Also, just because it doesn't crash from the console, doesn't necesarilly mean the code is working correctly, it could still be breaking, just not in a way thats triggering an access violation. The first thing I would look at is using p/invoke to call your unmanaged dll directly, if it breaks, you should know pretty quickly:
Calling Win32 DLLs in C# with P/Invoke
It could be that somewhere in the mix, this pointer is being moved to a different address space where that pointer makes no sense. Are there any process boundaries here?
Related
I'm working on a project that involves receiving a byte[] from a web page in a .net program, then loading that byte[] as a dll. However, the dll is not a .net assembly, it is a native assembly. I can't use loadlibrary because I would have to write to disk, and I want to keep the native dll in memory. I can't use c++ /cli, because this is all being done in mono, and mono doesn't support c++ /cli. Is there a library or project somewhere that allows me to load a native dll from a byte[], in c#? I've seen this tutorial: https://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/, but this is c++.
This will help you, or lead you somewhere.
This is basically a wrapper for the project you have sent, I will keep the repo up for anyone who wishes to look at It. Untested on 32bit OS, so It might do an overhead.
https://github.com/dretax/DynamicDllLoader
It basically does what you want. Expects a native dll's byte array, and loads it into the current process.
Just use Assembly.Load (if that's .Net assembly) https://msdn.microsoft.com/en-us/library/h538bck7(v=vs.110).aspx.
Otherwise, use PInvoke with unmanaged DLL's.
I will give you a short rundown on where problems with that lie:
You are receiving a DLL from the internet. Every adminsitrator will wonder if he just got insane or that really stands in the "how it works" description. We had enough problems with remote code excecution and code injection on data arrays in the last century to know how this will fail without needing to try.
Anything in the design of the managed .NET Runtime is there so you can not do shit like that. You propably have to go to unamanged code. And at that point, you might as well write in native C++.
It might even trip over some run off the mill virus scanners heuristics just for trying to pull this. Because that is on the short list of things a visitor to my Operating System should never try to pull.
You really, really should just burry that idea and live without it. If you got a boss that wants this, say him it is between impossible and figuratively insane. Possibly even literally insane. Even if you could make it, no admin of sound mind would install it.
If that has not detered you: It might be best to move this into a helper process of some sort, then transmit data/results via Interprocess Communication. When calling old, umanaged, never-migrated-to-64-bit DLL's from a .NET Application, missmatching binarity is often a problem. A helper process (that always runs at x32 to match the DLL) can help with that. And once you got a helper process, it can be programming in something like Native C++ where these kinds of shenanigans are easier and you even go a example.
I'm working on an app that I would really like to write in C#, but I need to use a library that is in C++. The vendor supplements their DLL with some C++ code to make the API more convenient, which it does, but it's still C++. I'd like to incorporate this extra C++ code into my app. It seems reasonable to create a DLL to wrap the vendor-supplied C++ code and the other calls into a module that I can use in C#.
My question is, does it make sense to wrap a DLL in another DLL? Are the potential problems I should watch out for?
Best,
John
Wrapping a wrapper for the sake of creating a better API (or, in your case, a .NET API) is OK. You might face some interop problems, as they can always pop up when moving from managed to unmanaged code.
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.
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.
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.
When calling functions with P/Invoke, you don't add the DLL to the C# project resources (or what you probably meant, references, either).
You will add it to the file list in your MSI project, of course.
I recently wrote a quick VB.NET app that injects a DLL into a running process. To test it I was creating my own vb.net Class Library project which simply spawns a "Hello World" message box in hopes of it showing up in the target process once I injected my HelloWorld.DLL.
My problem is that the message box never shows up after I inject the HelloWorld.DLL. I'm pretty sure the reason for this is because once my HelloWorld.DLL is injected (since it's a VB.NET DLL) it does not have a DllMain and hence has no idea what to execute and nothing happens.
Do I have to make my injection DLL in C++ so it has a DllMain? Is there anything I can do as a work around? Or am I completely wrong about everything.
Any insight would be greatly appreciated. Thanks.
While the .NET DLL is technically an extension of the PE format it is that extension that makes it intrinsically different to a DLL that contains pure compiled, native code. In order for the .NET code (managed code) to be run is will need to be executed by the .NET interpreter and withing the context of an AppDomain.
Essentially there is a load of stuff that .NET will do to get that code up and running.
Microsoft (bless 'em!) have written and article outlining what you need to do here http://support.microsoft.com/kb/828736
Another option is to not write pure C++ code, but instead to create a managed C++ project which will be much easier in getting the two to play nicely together. BTW having a managed C++ project doesn't mean all the code has to be managed either AFAIK
I'm currently in a project that need to work both on Mac and Windows. We are using standard portable C++ for all the application logic. However, since we want the app to feel totally native on both platform, the GUI will be written with C#/WPF for Windows and Objective-C/Cocoa for Mac.
However, for the windows part, I am wondering what is the best way to use the C++ code with C#. C# is managed, and I know that we can use managed C++ too. However I worry that using C++ inside the CLR may introduce unexpected bugs, or that we will need to put an awful lot of #ifdef WIN32 everywhere in the C++ code to make it work both with the managed CLR and the unmanaged environnement of Mac OS X (note that we sure expect to put some ifdef, but we'd like to keep it under control if possible). So basically, what is the best way to use the C++ code with the C# code? Right now, I'm thinking of three solutions
1- Compile the C++ as C++/CLI and directly use the classes and function from C#.
2- Compile and wrap the C++ in an unmanaged win32 dll and call it from C# using DllImport
3- Wrap the C++ in a COM wrapper and use the .NET COM Interop to link it with C#
Which one is the best way? Or, if there is a better solution, what is it?
C++/CLI has several restrictions over standard C++ that don't always make it easy to recompile standard C++ as C++/CLI. Keep in mind that you'll have to distinguish 'managed' and 'unmanaged' pointers, for starters. As these are using different symbols, you've got your first set of #ifdefs right there. And then you get to ref and value classes and all that sort of fun.
You can however use C++/CLI to bridge the gap between native code and the .NET world. The last time I did something along the lines of what you're planning to do, I used C++/CLI to write the bridging layer that did the necessary translation and conversion work between .NET types and classes and the native world. The C++/CLI layer can obviously be used from any .NET language.
You can't always use (2) - this depends very much on the data types you're trying to exchange between the two worlds. The .NET marshalling code is pretty good at dealing with C PODs but anything more complicated and you've got a problem.
(3) is overkill IMHO and introduces another point of failure, plus you're then doing .NET <-> COM <-> native instead of the simpler .NET <-> native if you created your own bridging code. Not to mention that you add complication to your code that won't benefit the other OS you're targeting, namely OS X.
Our development team has been using C++/CLI compiled code with ASP.NET and WPF front ends for while now.
The first major issue we had was build time. The code base would be 150k lines (40+ projects) and took forever to link (due to linker issues we could not build the individual projects as DLL's). We were only able to resolve this issue by wrapping the code with managed C++ classes and building our projects as assemblies.
The second major issue was performance. We originally compiled with /clr (before pure option existed) and this resulted in double thunking of most of our calls that occurred in the managed C++ layer. We fixed this by switching to /clr:pure. By doing so we ran into an
issue where our assemblies resulted in having too many 'global' methods in the assemblies so they would not load. We had to split our assemblies further to solve this issue.
Best and easier way is to do it with .NET <-> COM because COM has much stronger bridge compared to native dll access inside .NET because it may lead to lots of memory issues and lots of troubleshooting time. Its easier to test COM inside any MFC project and get the trace information for debugging and when the component is ready it can be easily used inside .NET.
CLI will not let you use all features and unfortunately its fairly new so less documentation is available and you will not get good support for your questions.
Win32 dll and DLLImport has problems mainly to troubleshoot, because the exception thrown inside Win32 dll will not travel further along the stack instead it will simply crash and you will not get the reason. Where else in COM you can catch exception internally and the COMException thrown inside .NET will not crash your entire application.
COM will be little slower in performance, but it will be more organized and good design pattern to develop.