Thursday, 2 June 2011

How to call functions of unmanaged dlls from managed codes (Code included)

This was really a wonderful experience. I really struggled to get a solution to shake hand with an old generation.

For any one who is newbie, the tip is as simple as it is.

1) Know a term "Marshalling", which technically means, converting a datatype to byte streams in order to transport from one app domain (it could be from unmanaged to managed or vice versa) to another.
There is another big term called "UnMarshalling" which is of-course the reverse process for Marshalled objects
Marshalling is not restricted to variables, you can even marshal a structure as such.

2) Know how to use delegates.
A delegate is used to call a function or property without directly in touch. Delegate actually is like a broker to handle our function calls. Broker actually accepts our request, point to the right function that we are looking for, call it and give back its response in the way the actual function returns (A function returning bool type can be called only by a delegate that return type bool. signature should be same), without letting us know any thing about the actual function.
Delegates are reusable. Read more about it.

Q. Why is marshalling involved?
A. To avoid datatype mismatch while invoking. All the .Net datatype may not be there in the primitive C/C++. Byte stream is commonly known to old and new dll/app makers. (Like the language English, used around the world for communication)

Q. Why is delegate important?
A. The unmanage library methods cannot be accessed directly from .Net, because they cannot be referred to our project like any other managed dll.

So, lets get in to coding.
Suppose our unmanaged dll is DLLClient.dll.
Suppose there is a function named "vEnableLogs" inside DLLClient.dll

#All references for the inside of DLLClient => Tech Ref that was supplied along.

Step 1. Know the vEnableLogs prototype and signatures
This function accepts a string and return bool.

Step 2. Create a delegate for the said function type, ie, delegate that has one string parameter and returns bool; see below for syntax
delegate void _vEnableLogs(string logPath);


Step 3. MAIN PART. The following is how you bring the function inside unmanaged dll to the outside world.
Lets say the opening to the function..

[DllImport(@"DLLCLient.dll"
 EntryPoint = "vEnableLogs",
ExactSpelling = false
CallingConvention = CallingConvention.Cdecl)]
static extern void vEnableLogs(string logsPath);


a)DllImport
This is used to import dlls, primitive method of importing dlls in to vicinity.
b) @"DLLCLient.dll"

Name of the dll. Located in the same directory as my working dll, or else you can give an associated or relative path.
c) EntryPoint = "vEnableLogs"
Name of function inside DLLClient.dll
d) ExactSpelling = false
An available property.
e) CallingConvention = CallingConvention.Cdecl
Read more here.
f) static extern void vEnableLogs(string logsPath);
static means we are not providing the code. Code is some where else.

4) By now the ingredients are ready for mix. Do the coding
public static bool My_vEnableLogs(string logsPath)
{
    _vEnableLogs enableLogs = new _vEnableLogs(vEnableLogs);
    return enableLogs(logsPath);
}

Every external programs will call this function ("My_vEnableLogs"). Static, well that is all up to us. Delegate can be accommodated in either.

No comments:

Post a Comment