I am trying to reference a .Net DLL(call it B.dll), which basically is a wrapper for a .Net third party(call it C.dll), into c++ MFC project. I did create the tlb file for B.dll and am able to instantiate and call this within the MFC app.
At the moment all the dependencies, B.tlb, B.dll and C.dll, need to be in the bin
folder of the MFC application. What I want, and am struggling to do, is to put these three files in a sub folder of the MFC execution folder.
I tried setting the "privatePath" of the B.dll config file to a sub folder but as I understood it, it's not the B.dll "privatepath" that needs to be set but the MFC application(which obviously hasn't got any as far as I know, as it's not a .Net application)
Any help is appreciated.
You don't need to use COM (if you need it my answer is obsolet).
You can write your own C++/CLI wrapper DLL that has just exports a native interface. Than call you can this native wrapper and this wrapper again loads your .Net component directly and executes the code in it.
In this wrapper DLL you can add an ResolveEventHandler where you implement your own search (maybe in the subdirectory). Add this to your CurrentDomain->AssemblyResolve
With this trick you get around all this COM stuff, and you have full control were assemblies should be searched for that can't be loaded.
I have the solution from here
Related
I have a c++ project compiled with /clr support(e.g. wrapper.dll). This project(wrapper.dll) is a wrapper between .Net enviroment and unmaged dll(e.g. noCode.dll), which inherits from. I dont have access to code of inherited dll(noCode.dll), but I can link it to my wraper (by noCode.lib and noCode.h files).
When I want to use my wraper(wrapper.dll) in c# project I reference it and have to copy my unmanaged dll(noCode.dll) to location of c# project execution.
Is it possible to merge c++ unmamaged dll(noCode.dll) to managed dll(wrapper.dll) to allow to use only one file by reference(noCodeWrapper.dll) in c# projects?
It is not possible to link DLL files together.
But you can add that nocode.LIB to your DLL and then you don't need [DllImport]. Since you have LIB and H files, you can call the "nocode" functions directly from your managed C++ code.
If you had access to noCode.dll source code you could integrate it with wrapper.dll. Otherwise merging DLL binaries is not a task that could give predictable results.
Usually when we need to use native C++ DLL in C# program, write a manage wrapper is the way to achieve it.
Inside such program, If I press F12 (go to function definition) on a DLL function call, It goes to a C# file that looks like having all the functions forward declarations. I check the location of this file and it exist in the windows temp directory.
So my question is , When we uses a C++ unmanage DLL by manage wrapper in a C# program, Does .NET framework ( or any other component) create any temporary C# classes relevant to interface classes in the DLL?
There are no "temporary C# files". If you use Go to Definition and the IDE only has an assembly reference for the definition then it doesn't have a shot at finding the source code file for the definition. So it auto-generates one from the metadata in the reference assembly. That looks fairly similar to a source code file, but of course without any comments and without the code for the classes. It cannot be compiled. It is also in C#, even if the original assembly was created from C++/CLI or VB.NET code.
Nice feature, but don't confuse it for anything more than it is. If you want the IDE to take you to the actual source code file then you need a project reference, not an assembly reference, for the library.
I have several Unmanaged C++ written lib files which I need to link to Managed C++ dll.
Then I need to invoke functions of this Managed C++ from C# application.
First step is OK - Managed C++ dll is created, I can see with ildasm that it exports functions I need. However when I try to call this function from my C#-written test app it says:
An unhandled exception of type 'System.IO.FileLoadException' occurred in Unknown Module.
A procedure imported by {MyManagedCPP.dll} could not be loaded.
This message goes from VS2010.
I made simple experiment - removed dependencies from all lib files in Managed C++ dll and rebuild it.
With this change it is OK - app starts, I can call functions of Managed C++ dll from C# test app.
Is it not possible by design to call managed c++ functions when dll has static linkage with lib files? Technical restriction? Or there is some workaround?
Thanks
You no doubt have an implicit dependency on a native DLL. It isn't clear from the question what DLL that might be. It could be msvcrxx.dll for example, a runtime support library for native C++ code. Which would be rather bad, you don't want to mix CRT versions. Such a missing DLL otherwise prevents the C++/CLI assembly from getting loaded, producing the FileLoadException.
If you have no idea what that DLL might be then you could use SysInternals' ProcMon utility. The trace will show you the program searching for the DLL and not finding it. If it is msvcrxx.dll then be sure to rebuild the .lib files using the same compiler version you used to build the C++/CLI assembly. If it is something else then make sure you copy that DLL to the build directory.
I've created and registered a managed COM library in C# on my development machine. I've successfully registered it and created a .tlb file with regasm, and successfully imported the tlb into a c++ console app used for testing.
My COM assembly is called "efcAPI.dll" and it references another assembly that has not been set up for COM or registered in anyway called "efcServerDiscovery.dll". This second dll contains some code used by my COM dll and exists in the same folder as efcAPI.dll.
Everything concerning loading the COM assembly works fine. I can create instances of my classes defined in the COM and call methods from them. However when I call certain methods that use the code defined in efcServerDiscovery.dll I get a _com_error which reports that it could not load file or assembly 'efcServerDiscovery'.
I've verified that everywhere on my hard drive where efcAPI.dll exists there's a copy of efcServerDiscovery.dll (which is just the location I built and registered efcAPI.dll from). I've also attempted to place efcAPI.dll and efcServerDiscovery.dll in the same directory as the c++ app with no success.
Any suggestions as to where the c++ app is looking for the assembly or how to discover where it's looking would be great!
Yes, this is a problem with COM components having non-COM dependencies. Windows doesn't consider the location of the COM DLL when it searches for dependent DLLs. The normal search rules are in effect, the folder that contains the EXE first, Windows directories, current working directory, PATH environment. The location of the COM server does not play a role.
Assuming you don't want to deploy to the EXE folder, none of these are good places to store your DLL, although plenty of installers made the desperation move of storing it in c:\windows\system32 or modify the system PATH environment variable.
One thing you could do is P/Invoke SetDllDirectory() in your C# code before running any code in the DLL. Using Assembly.GetExecutingAssembly().Location will do it. That is however not a safe thing to do though, it might alter the search rules for the app that uses your component.
The only real fix is to install the DLL in the Windows side-by-side cache (WinSxS) and to include a manifest in your C# executable. Given the state of the documentation, I can only wish you the best of luck.
In these situations i always start with Dependency Walker verifying that what & where its trying to load is what i think it is.
fuslogvw will tell you where the CLR is looking for assemblies
Or use GAC.
(here are your characters, stackoverflow)
My UserControl references a C++/CLI wrapper to an unmanaged C++ dll. When I try to add the UserControl to a form, I get a Visual Studio error, which says "Failed to create component 'userControl'", giving a System.IO.FileNotFoundException as the cause.
From what I've been able to determine, the problem stems from visual studio not copying the C++/CLI wrapper assembly's unmanaged dependencies. If I put the unmanaged dependencies on the system PATH, everything works fine.
Is there a better way of doing this?
The easiest thing to do would be to include the actual .dll in your project, mark its build action as "Content", then set the Copy to Output Directory to "Always". This should get the .dll into your output directory so that your application can run, and just including the file in the project should put it in the project directory so that the designer can find it.
Be sure that your setup project includes a project output for the Content files from that project as well.
Edit
If those don't work, you can also edit the reference paths of the project itself (in the project properties), though I am not certain that this will affect the designer. If that doesn't then your only real option is to have the .dll in one of the system path directories.
Old thread, but submitting my solution since I just encountered the issue and found this question during the process.
Basically I just made the native DLLs to be delay loaded in my wrapper C++/CLI library. Since the C++/CLI part of the wrapper contains the interface specs used by Visual Studio and the framework, the native DLL is never needed or loaded. I answered it with a little more details in this question too:
https://stackoverflow.com/a/15481687/34440