Вызов GetProcAddress из VBA всегда возвращает значение null

У меня 64-битная Windows 10 с 64-битным MS Office. Я пытаюсь заставить VBA для Powerpoint загружать и выполнять функцию в самописной 64-битной DLL-библиотеке Windows. Чтобы предотвратить искажение имени экспорта, я использовал extern C:

extern "C" {
    __declspec(dllexport) long jaadd(long a, long b)
    {
        return a + b;
    }
}

Эту простую функцию можно вызвать из модуля C++ без проблем:

    hinstDLL = LoadLibrary(L"D:\\Visual Studio 2017\\Projects\\PopUpDLL\\x64\\Debug\\PopUpDLL.dll");
    if (hinstDLL != NULL)
    {
        jaadd = (AddFunc)GetProcAddress(hinstDLL, "jaadd");
        if (jaadd != NULL) {
            result = jaadd(13, 40);
        }       
        fFreeDLL = FreeLibrary(hinstDLL);
    }

Проблема возникает при попытке вызвать DLL из VBA в Powerpoint. GetProcAddress всегда возвращает ноль, как и FreeLibrary.

    Private Declare PtrSafe Function FreeLibrary Lib "kernel32" (ByVal      hLibModule As Long) As LongLong
    Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
    Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private hLib As Long
    Sub LLib()
        hLib = LoadLibrary("D:\\Visual Studio 2017\\Projects\\PopUpDLL\\x64\\Debug\\PopUpDLL.dll")
        MsgBox hLib
        Dim pprocaddress As Long
        pprocaddress = GetProcAddress(hLib, "jaadd")  ***** always returns 0
        MsgBox pprocaddress
        xx = FreeLibrary(hLib)  ***** always returns 0
        MsgBox xx
    End Sub

Любая помощь принята с благодарностью.


person Jon Anthony    schedule 15.04.2017    source источник
comment
Попробуйте Dim pprocaddress как LongPtr. То же самое с hLib, я думаю.   -  person Rich Holton    schedule 15.04.2017
comment
Заявления Declare неверны, дескриптор — LongPtr.   -  person Hans Passant    schedule 15.04.2017
comment
Спасибо вам обоим. Это заставляет вещь работать. Так много веб-сайтов в своих операторах DECLARE имеют дескриптор LoadLibrary и возвращают GetProcAddress как Long вместо LongPtr.   -  person Jon Anthony    schedule 18.04.2017


Ответы (1)


Вы каждую попытку

Private Declare PtrSafe Function jaadd Lib "......\x64\Debug\PopUpDLL.dll" 
Alias "_jaadd@8" (ByVal arg1 As Long, ByVal arg2 as Long) As Long

Обратите внимание на «алгоритм» изменения псевдонима: _ + ваше исходное имя + @ + сумма байтов аргумента.

У вас есть два VBA Long или два целых числа C#, 4 + 4 = 8.

Вы также можете обойтись без близнецов здесь, в стране VBA.

См. также https://docs.microsoft.com/en-us/office/client-developer/excel/how-to-access-dlls-in-excel

Наконец, убедитесь, что вы используете 32-разрядную DLL для 32-разрядного VBA и 64-разрядную DLL для 64-разрядного VBA.

Так много веб-сайтов в своих операторах DECLARE имеют дескриптор LoadLibrary и возвращают GetProcAddress как Long вместо LongPtr.

Проблема в том, что информация устарела - код никогда не обновлялся, чтобы отразить состояние VBA после Excel 2009.

person V. V. Kozlov    schedule 07.02.2020
comment
Спасибо за ваш комментарий и веб-ссылку. Два комментария выше помогли мне. - person Jon Anthony; 09.02.2020