As a test, I am writing a small C++ .DLL to be invoked from C#. Reading MSDN it looks like I need a C# wrapper which is also to be a .DLL.
So in all a C# program as an .EXE, invokes a wrapper which is a C# .DLL, which in turn invokes the C++ DLL.
My problem is that at runtime the invoking program gives an error "unable to find an entry point named DoStuff", where DoStuff is the C++ method.
I think it might be because DoStuff is a method in a class and the method is declared with the class name in front. So in the .h include file:
public class Half
{
Half();
~Half();
double DoStuff(double arg);
}
In the .cpp file:
double Half::DoStuff(double arg)
{
return arg/2;
}
I am not sure if the Half:: qualifier is the cause of my problem but the trouble is that if I do not preface the declaration with Half::, then the C++ will not compile.
Please help.

1 answers
As DoStuff() is an instance function, you need a pointer to a C++ Half object so that you can P/Invoke the function using the 'ThisCall' calling convention which passes 'this' as the first parameter. However, AFAIK*, there's no direct way to P/Invoke Half's instance constructor using the 'new' operator to get the pointer you need.
You'd be better really creating a mixed mode C++/CLI dll to wrap your unmanaged C++ dll and then consume that from C#.
If you don't fancy that, then one thing you could do is to write a static 'Create' function for the Half class which calls the instance constructor internally and then returns a pointer to the instance to the caller. You should then be able to P/Invoke the static function OK.
(* There is in fact a way - see Second Edit below)
EDIT
I thought I'd see if I could get an example working of adding static Create and Destroy functions to your C++ dll so that you can then call instance functions directly from a C# program.
As you'll see I've made the C++ dll a little more interesting by adding a field and another instance function to the Half class.
I've also created global (rather than static) Create and Destroy functions so that we can export them using C linkage which prevents the names from being "mangled".
However, this isn't possible for the instance functions whose names are therefore mangled and, in the C# code below, I've used their 'ordinal' numbers within the dll (you can get these from Dumpbin or Dependency Walker) rather than their mangled names as the entrypoint:
Other than that I think you'll find the code, which works fine, reasonably self-explanatory.
SECOND EDIT
I've been looking into this some more and there is in fact a way to do this without adding global Create and Destroy functions to your C++ dll. However, you need to do your own memory management and therefore need to know how much memory the C++ object requires on the unmanaged heap. You can then use a pointer to this memory to P/Invoke the constructor and, when you're done, P/Invoke the destructor and free the memory.
In this case the C++ class only has one field - a double - and so 8 bytes of memory is needed.
Here's the code on this basis. Notice that the ordinal numbers of the two instance functions have changed now that we're exporting the constructor and destructor as well:
In practice, unless you only wanted to call a couple of functions, you'd probably want to use this technique to wrap your C++ class into a C# class which implemented IDisposable etc. and would ensure you didn't miss out any of the steps.
answered one year ago by:
17279