Difference between dllimport and getProcAddress
Asked Answered
W

2

6

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?

Wickedness answered 13/7, 2010 at 23:27 Comment(0)
W
6

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.

Waterer answered 13/7, 2010 at 23:32 Comment(4)
Thank you for your answer. In my code, I actually loaded the library in the constructor, freed the library in the destructor, and used the whole thing as a singleton, since I didn't know if it would cause trouble to load the library more than once. In the interest of correctness I have edited my post to also free the library.Wickedness
@Boris: LoadLibrary and FreeLibrary do reference counting, so multiple calls tend to work out ok.Wrong
What do you mean by "leaking addresses"? The DLL is loaded only once, only one copy of the function exists in memory, and the delegate is garbage collected.Wrong
@Ben: It actually keeps extra pointer counts in memory, though - it's not a big deal, since the library's loaded 1 time only due to reference counting, but you do actually leak a pointer, and it's probably better to unload the library if you're not going to keep using it anyways...Waterer
W
4

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.

Wrong answered 13/7, 2010 at 23:36 Comment(2)
Ben: Just an FYI - You can do this with [DllImport] by having the library in a separate path, and changing the search paths at runtime.Waterer
You mean messing with the PATH environment variable? Not recommended. blogs.msdn.com/b/oldnewthing/archive/2008/12/11/9193695.aspxWrong

© 2022 - 2024 — McMap. All rights reserved.