views:

1773

answers:

5

I have a C++ DLL (no code) that I want to expose to .NET applications.

After pondering all the options I have/know of/could find (COM, P/Invoke, SWIG, etc.), I'm writing a .NET Class Library (in C++/CLI). Now the resulting DLL (class library) requires the original DLL and its dependencies, too. My problem lies in automagically keeping track of such things, so that applications that use the wrapper don't have to keep track of the other (native) DLLs (especially if the original DLL(s) develop a new dependancy).

To be more precise (and have something concrete to discuss), I'm trying to wrap cmr, so I write MR, the class library (which depends on cmr, naturally). cmr depends on PNL, OpenCV, and others. When I tried adding a reference to MR in a (C#) project, Visual Studio (2005 SP1) just copied MR.DLL, leaving all the dependencies behind, and then complaining (throwing a FileNotFoundException about missing modules). Manually copying cmr, PNL, etc. to the bin directory fixed the problem.

Without further ado, my question is this: Is there a way for .NET apps to only add a reference to one DLL, and everything just works?

I've been scouring through Google and SO, to no avail...

EDIT: mergebin seems the closest to what I'm looking for, but it can only merge a .NET DLL with one native DLL. Too bad one can't merge native DLLs.

A: 

Sounds like you have two specific issues:

  1. How to copy over the native code dlls before the build starts
  2. How to dynamically figure out the native code dependancies that need to be copied over in case they change.

For 1), you could use a pre-build step in your C# project to call a custom util to copy over the correct files.

Looks like 2) has already been answered here on Stack Overflow.

Casey Chamberlain
A: 

Well, you could simply add commands to automatically copy the required DLLs into the correct output directory, as part of the Build process. This is done in Visual Studio by going to the project's properties.

Project -> MyProjectName Properties... -> Build Events

Add the commands to copy the files you need into the $(TargetPath) and you're done.

Another option would be to simply set the current working directory of your project (when you're running it from within Visual Studio only) to be the directory in which all the DLLs you need reside. You'll still have to manually copy the files when executing the program externally, but it will make development a little easier.

scraimer
+4  A: 

You might take a look at mergebin, a tool that allows you to combine unmanaged and managed DLLs into one assembly. System.Data.SQLite uses this approach.

Darin Dimitrov
A: 

I'm currently having a very similar problem.

One big step too meet my goal was to copy the Native .DLL into the output directory by a pre-built step in the C++/CLI project and add the linker option

/ASSEMBLYLINKRESOURCE:"$(OutDir)\Native.dll"

This writes into the resulting assembly that there is a file "Native.dll" that belongs to the assembly. Now all projects referencing that project/assembly will also copy the Native.dll around! (It should also go into the GAC if you put you're assembly there - I didn't check that).

Okay, you still have to add all depending native.dll's. I also don't know if the native DLL is found on run-time if you load the assembly via Assembly.LoadFrom() from a very different path (this is something I have to solve for my problem because our C++/CLI wrapper assembly is needed by the Visual Studio designer).

I hope this helps you a bit for you're problem.

EDIT:

Further investigations showed that the Wrapper .DLL always finds the native .DLL...that's the good thing. The bad thing is that the Visual Studio Designer copies the needed assemblies to a temporary directory (somewhere inside the user directory) when you open a form. When it copies the assemblies it ignores the linked resources and by this the native .DLL!

rstevens
A: 

how can i add a c++ dll in my .net application??

mony