I'm trying to PInvoke into this C++ library function:
int Initialize(Callback* callback);
struct Callback
{
//.......
void virtual StateChanged(int state) = 0;
};
I have tried this naive C# code, but it doesn't work.
[DllImport("CPlusPlusLibrary.dll", SetLastError = true, EntryPoint = "?Initialize#CPlusPlusLibrary##YAHPAUCallback#1##Z")]
public static extern int Initialize(Callback callback);
[StructLayout(LayoutKind.Sequential)]
public class Callback
{
//....
public delegate void IntDelegate(int state);
public IntDelegate StateChanged(int state);
}
var callback = new Callback();
var result = Initialize(callback);
It is impossible to do it that way as far as I know. Methods are not "in there" as fields would be, beside this, creating a struct with virtual method will create a vtable pointer in your objects, that you are not taking into account in c# mirrored class.
What you can do is to PInvoke to method that takes a functionPointer (in C++) and pass a delegate (C#) there. You can then use this function pointer to call it from native code and your delegate will launch.
You could then change your stateChange method definition to take a Callback* as a first parameter, so when you call it from native code you can pass an object pointer which is responsible of that change and marshal it back to Callback in c#.
//Edit without having source of native dll, building a bridge between c# and c++ is what comes to my mind. This can be done with c++/cli or c++, sticking to native my idea would be something like this:
//c++ <--> new c++ dll <--> c#
struct CallbackBridge : public Callback
{
void (*_stateChanged)(int);
virtual void stateChanged(int state)
{
if (_stateChanged)
_stateChanged(this, state);
}
};
void* CreateCallback() { return new CallbackBridge(); }
void DeleteCallback(void* callback); { delete callback; }
void setStateChanged(void* callback, void (*ptr)(void*, int))
{
CallbackBridge* bridge = (CallbackBridge*)callback;
bridge->stateChanged = ptr;
}
///... other helper methods
The idea here is to treat your object as a black box (hence void* everywhere - it can be any pointer, but from c# you will just see this a a SafeHandle / IntPtr and write helper methods that you can PInvoke to to create / delete and modify objects. You can mock those virtual calls by giving your object a delegate through such method.
From c# usage could look like this: (IntPtr for simplicity, SafeHandle could be used):
IntPtr callback = CreateCallback();
SetStateChanged(callback, myCallback);
//somewhere later:
DeleteCallback(callback);
void MyCallback(IntrPtr callback, int state)
{
int someData = SomeOtherHelperMethod(callback);
ConsoleWrite("SomeData of callback is {0} and it has changed it's state to {1}", someData, state);
}
I know, it's a bit clumsy for bigger objects, but without c++/cli wrapper I have never found any better way to be able to handle all those tricky cases like virtual calls etc.
Your C# class is no substitute for the C++ struct, it has an entirely different internal organization. The C++ struct has a v-table because of the virtual method. It is not a POD type anymore. It has a hidden field that contains a pointer to the v-table. And a compiler-generated constructor and destructor. The v-table is an array of pointers to the virtual methods. A C# class has something similar, called "method table", but it organized completely differently. It will have the System.Object methods for example and contains pointers to all methods, not just the virtual ones. The class object layout is completely different as well. The struct keyword in the C++ language in this context is just a substitute for the class keyword with all members public by default.
A wrapper class written in the C++/CLI language is required. There's a bit of a learning curve to the language but it is not steep if you've got experience with .NET and C++. Boilerplate code for such a wrapper is in this answer. You can call back from native code into managed code through a function pointer returned by Marshal::GetFunctionPointerForDelegate().
I have heard that you don't have the source code of C++ library. Then you might have a look at this.
But exporting classes from unmanaged dll to managed one without source sounds dangerous to me.
Related
I am trying to use a native dll using DllImport in C#. Most of the methods are working fine but I am stuck in registering to callbacks. here is the sample:-
The function used for callback is static int SetReceiver(IMessageReceiver* pReceiver);
Definition for IMessageReceiver is
class IMessageReceiver
{
public:
virtual void OnMessage(unsigned char ucCommand, const void* pData, size_t size) = 0;
};
In C++ it is done like this:
class A : IMessageReceiver{ implementation of virtual function}
SetReceiver(this); // this is object of Class A.
I want to achieve same in C#. What i did is created one Interface IMessageReceiver and implemented in class. I am creating the object of that class and passing it as parameter but getting exception.
[DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetMessageReceiver(IMessageReceiver pReceiver);
SetMessageReceiver(pReceiver);
You are not going to be able to solve this from your C# code. You need to provide the implementation of a C++ class. And you cannot make one of those in C#.
The only way to solve this is with C++ code. I can see a couple of obvious solutions:
Use a mixed-mode C++/CLI assembly. That can implement the unmanaged C++ class and provide a bridge between the unmanaged C++ code and the managed C# code.
In your C++ code add a concrete implementation of IMessageReceiver that implements OnMessage by forwarding to a function pointer. The function pointer can be provided by the C# code. You'll need to wrap this up in a C style function so that you can p/invoke it.
I'm writing a C# wrapper around a native dll that uses opaque pointers to identify resources. A typical example would be something like
typedef struct session session;
typedef struct track track;
void* sessionCreate(int arg, session** sess);
void sessionRelease(session** sess);
track* sessionGetTrack(session* sess, int index);
void trackAddRef(track* trk);
void trackRelease(track* trk);
int trackGetLength(track* trk);
In my wrapper, I've created C# classes corresponding to the different opaque types, with member functions corresponding to the various functions using the different opaque types.
This is fine. There are also callbacks from the dll, for example
void(* track_changed )(track *trk, bool changedExternally);
In order to map from the static delegate that handles the callback to the object that corresponds to the handle supplied, I'm using a static dictionary of WeakReferences (IntPtr/SafeHandle as key, object reference as aata) in each of my classes.
So what is the right way to approach removing entries from the static dictionary? I'm writing library code and cannot rely on my clients to Dispose my objects. Should the I put the code in the finalizer?
Or is there a better way to manage the correspondence between the static callbacks and my object instances?
Your clients really should (indeed I would prefer to say must) dispose of your objects since they are IDisposable, just like they do with other BCL classes.
In any case a bog-standard implementation of the dispose/finalize pattern should cover all bases. There is more related discussion here.
I have a c++ dll which I need to use in my .NET code.
How do I call methods on this library, and use the result in my code?
e.g. C++ library has a method called Move(int) which returns a 1 for true and a 0 for false.
I didn't write the C++ library, it is used to control the movement of a robotic machine.
You could use P/Invoke. So for example if your unmanaged library exports a function which takes an integer value as argument and returns another integer you could define a managed wrapper for this method in C# decorating it with the [DllImport] attribute:
[DllImport("foo.dll")]
public static extern int Move(int arg);
and then use this method directly in managed code:
int result = Move(123);
http://msdn.microsoft.com/en-us/library/ms173184.aspx
using System.Runtime.InteropServices;
...
public class MyClass
{
#region PInvokes
[DllImport("Your.dll")]
static public extern int Move(int val);
....
If, once, you would have to Interop C++ classes, here is a good article about it.
http://www.codeproject.com/KB/cs/marshalCPPclass.aspx
Are callback functions equivelent to events in C#(.NET).
What I understand about callback function is, it is a function that is called by a reference to that Function.
Example Code will be:
void cbfunc()
{
printf("called");
}
int main ()
{
void (*callback)(void);
callback=(void *)cbfunc;
callback();
return 0;
}
Now What I dont understand is How is this use full with respect to notifying from the DLL to client.
Suppose I want to do /perform some method1() when I recieve Data on my DLL method2().
Any comparasion with Events in .NET will be helpfull in a great way.
Callbacks and interface classes are great ways to manage your code boundaries. They help create formal boundaries and/or layers in your code instead of lumping everything together. This becomes necessary when working on large software solutions.
Below is an example of how to use callbacks and interface classes. In the library/dll code the only thing that should be exposed to the main executable is the myddl_interface class and the function getMyDllInterface(). Using an interface class like this completely hides the implementation detail from the main executable. The interface class also allows the main executable to register a function with it that will be executed later (i.e. callback).
// Begin library/dll Public Interface used by an executable
class mydll_interface {
public:
typedef void (*callback_func_t)();
public:
virtual void do_something() = 0;
virtual void registerFunction( callback_func_t ) = 0;
};
static mydll_interface* getMyDllInterface();
// End library/dll Public Interface used by an executable
// Begin library/dll Private implementation
class mydll_implementation : public mydll_interface {
public:
void do_something() {
printf("Hello World\n");
_callback_func();
}
void registerFunction( callback_func_t c) {
_callback_func = c;
}
private:
callback_func_t _callback_func;
};
static mydll_interface* getMyDllInterface() {
return new mydll_implementation();
};
// End library/dll Private implementation
// Begin main executable code
void myMainAppFunc() {
printf("hello World Again\n");
}
int main() {
mydll_interface* iface = getMyDllInterface();
iface->registerFunction(&myMainAppFunc);
iface->do_something();
};
// End main executable code
You pass the pointer to a 3rd-party routine (doesn't have to be a DLL) and it is "called back" when notificastion is required, by the cloned pointer.
It is similar to .net events in that the latter are also a type of a callback.
BTW, DLLs are less popular in C++ than they are in .NET. This is due to impossibility of sharing static variables (and therefore, singletons), the problem also known as lack of dynamic linking (in UNIX systems, this is solved with Shared Objects, which are quite a different concept of dynamically loaded library). Static libraries offer a better code reuse strategy.
Callback functions fulfill a similar purpose to delegates in C#.
For example, the Win32 API provides a timing service, that is accessed by calling SetTimer. SetTimer is exported by a system DLL, but the mechanism is exactly the same as if used in a user dll. In your code you would access the timer by doing something like this:
void
CALLBACK
MyTimerCallback(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
// do something
}
...
TIMERPROC fn = &MyTimerCallback;
int delay = 500;
SetTimer(NULL,0,delay,fn);
Calling SetTimer, and passing in the callback function, allows the operating system to call back into the function each time the timer ticks. Of course, there is no multicast capability here, and, especially in the case of SetTimer, the callback function must be a C function or static class method. There is no class or object instance associated with the function.
A similar pattern could be done in .NET - Im sure .NET has its own Timer paradigm but for a moment we could pretend that it implements a SetTimer function that takes a TimerDelegate.
In user code, in an object you would then define the MyTimerProc as a function with a signature that matches the delegate. And invoke it like this
TimerDelegate d = new TimerDelegate(myObject.MyTimerProc);
SetTimer(0,0,delay,d);
Or, if "timers" was an event that matched the TimerDelegate, then the equivalent C# code would look something like:
timers += new TimerDelegate(myObject.MyTimerProc);
Note: My C# is very rusty so don't take those code samples as any kind of example of either best practices, or even working code :P
When defining your own callback functions it is good practice to always define callback functions to take a void* "context" parameter, as that allows C++ programmers to store their "this" pointer and retrieve it.
// the first parameter to the callback fn is a void* user supplied context parameter
typedef void (CALLBACK* MyCallbackFn)(void* context, int etc);
// and, the dll export function always takes a function pointer, context parameter pair.
DLL_EXPORT void SomeExportedFn(MyCallbackFn, void* context);
A notable example is qSort(), it needs a callback function to compare 2 items.
Callback function can leave some behavior decided at runtime.
If some behavior should be decided by client side dynamically at runtime, then I will ask clients to supply callback functions.
How can I use a C++ class in C#? I know you can use DllImport and have the class as IntPtr, but then how would I call the functions inside the class? And I don't want to create a new method for each method in the class and export that, then there is not point for me to use a class then...
Without creating a COM app
C++ Class:
class MyCPPClass
{
public:
MyCPPClass();
~MyCPPClass();
void call_me();
}
extern "C"
{
extern __declspec(dllexport) MyCPPClass* __cdecl CreateClass()
{
return new MyCPPClass();
}
}
C#:
class MyCSClass
{
[DllImport("MyCPPDll.dll")]
static extern IntPtr CreateClass();
public static void Main()
{
IntPtr cc = CreateClass();
// Now I want to call cc->call_me();
}
}
If you're building your classes in C++/CLI, then you just just be able to use it as you would any regular .NET class.
If the DLL in question is accessible via COM, then use the COM interop to talk to it from .NET.
If OTOH you're looking at non-COM, plain vanilla C++, you will have to ensure that all classes and their members are exported...
My suggestion would be that if you want to use a plain vanilla C++ DLL, write a C++/CLI wrapper around it that can "talk .NET" to your C# code and "real C++" to the C++ DLL. You'll still have to export all the C++ classes and functions, but at least that way you're working in the same language before you transition to C#.
To use c++ class, C++\CLI is a better option
As others have stated, C++ CLI is probably the easiest option.
The other standard option which you've started doing is to keep building on that C style facade you started and expose another method something like this:
extern "C" {
extern __declspec(dllexport) MyCPPClass* __cdecl CallMe(void* data)
{
MyCppClass* instance = (MyCppClass*) data;
instance->call_me();
}
}
then you can go through the tedium of creating a C# class that mirrors the functionality of your C++ class and hides the fact that the implementation is in another dll.
Or you could use C++ / CLI.