Разница между dllimport и getProcAddress - PullRequest
5 голосов
/ 14 июля 2010

Во-первых, я знаю, что нет смысла сравнивать атрибут dllimport и функцию getProcAddress напрямую.Скорее, меня интересует сравнение двух частей кода, которые в основном достигают одного и того же - вызова функции в dll - либо путем импорта функции с атрибутом dllimport, либо с помощью функции getProcAddress.В частности, я пишу приложение на C #, которое использует некоторую функцию в dll, которую я написал.Сначала я обратился к своей функции dll со следующим фрагментом кода:

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;
    }
}

Однако позже мне нужно было получить значение lastError, если оно было установлено во время вызова dll, поэтому я изменил свой кодв это:

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);
    }
}

Это, конечно, намного аккуратнее, и, как уже упоминалось, он устанавливает код lastError.Очевидно, что мой первый фрагмент кода дает мне возможность изменять dll и вызов функций во время выполнения, но на данный момент это не требуется.Поэтому мой вопрос: есть ли причины для использования первой формулировки, если я уверен, что я не буду использовать другую DLL или другую функцию?

Ответы [ 2 ]

5 голосов
/ 14 июля 2010

Единственным реальным преимуществом использования GetProcAddress является то, что вы можете выгружать DLL вручную, а также вызывать функцию, и что вы можете легко изменить наименование во время выполнения.

Однако второй вариант предоставляет вамогромное количество преимуществ.Помимо того, что он «аккуратнее», он также обрабатывает большую часть маршалинга типов данных для вас - что становится очень важным для определенных API.

При этом, если вы выполните метод, который вы перечислили первым,Вы также должны убедиться, что выгрузили все.Прямо сейчас, вы в основном просачиваете адреса каждый раз, когда вызываете Bar () ... Подробнее см. FreeLibrary .

4 голосов
/ 14 июля 2010

Вероятно, самое большое преимущество GetProcAddress заключается в том, что он позволяет вам контролировать путь поиска DLL.Например, вы можете автоматически загрузить 32-битную или 64-битную версию собственной DLL.С DllImportAttribute это невозможно.

...