Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between dllimport and getProcAddress

First, I know that it doesn't make sense to compare the dllimport attribute and the getProcAddress function directly. Rather, I am interested in comparing two pieces of code, that achieve basically the same thing - calling a function in a dll - by either importing the function with the dllimport attribute or with the getProcAddress function. Specifically, I am writing a C# application that uses some function in a dll that I have written. At first I accessed my dll function with the following piece of code:

class DllAccess
{
    [DllImport("kernel32.dll", SetLastError = true)]
    private extern IntPtr LoadLibrary(String DllName);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate Bool BarType(Byte arg); // return value indicates whether function call went well or not.

    Bool Bar(Byte arg)
    {
        Bool ok = false;
        IntPtr pDll= LoadLibrary("foo.dll");
        if (pDll != IntPtr.Zero)
        {
            IntPtr pfunc = GetProcAddress(pDll, "bar");
            if (pFunc != IntPtr.Zero)
            {
                BarType bar = (BarType)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(BarType));
                ok = bar(arg);
            }
            FreeLibrary(pDll);
        }
        return ok;
    }
}

However, I later needed to get at the lastError value, if it had been set during the dll call, so I changed my code into this:

class DllAccess
{
    [DllImport("foo.dll", EntryPoint = "bar", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
    private extern Bool DllBar(Byte arg); // return value indicates whether function call went well or not.

    Bool Bar(Byte arg)
    {
        return DllBar(arg);
    }
}

This is of course much tidier, and as mentioned, it sets the lastError code. Obviously, my first piece of code gives me the possibility of changing dll and function call at runtime, but at the moment this is not required. So my question is: Are there any reasons for using the first formulation, if I am certain, that I will not be using another dll or another function?

like image 791
Boris Avatar asked Jul 13 '10 23:07

Boris


2 Answers

The only real advantages of using GetProcAddress are that you can unload the DLL manually as well as call a function, and that you can change the naming easily at runtime.

However, the second option provides you with a huge number of benefits. In addition to being "tidier", it also handles much of the marshaling of data types for you - which becomes very important with certain APIs.

That being said, if you do the method you have listed as first, you should make sure to unload everything, as well. Right now, you're basically leaking addresses each time you call Bar()... For details, look at FreeLibrary.

like image 129
Reed Copsey Avatar answered Sep 30 '22 15:09

Reed Copsey


Probably the biggest advantage of GetProcAddress is that it lets you control the search path of the DLL. For example, you could load either 32-bit or 64-bit version of a native DLL automatically. With DllImportAttribute, this isn't possible.

like image 38
Ben Voigt Avatar answered Sep 30 '22 16:09

Ben Voigt