Calling GetProcAddress from VBA always returns null

孤街浪徒 提交于 2021-01-29 03:50:51

问题


I have 64 bit windows 10 with MS Office 64 bit. I am trying to get the VBA for Powerpoint to load and execute a function in a self-written 64 bit windows DLL. To prevent export name mangling I have used extern C:

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

This simple function can be called by a C++ module with no problems:

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

The problem arises when trying to call the DLL from VBA in Powerpoint. GetProcAddress always returns zero and so does 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

Any help gratefully received.


回答1:


Did you every try

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

Note the Alias mangling "algorithm": _ + your original name + @ + sum of argument bytes.

You have two VBA Longs, or two C# ints, 4 + 4 = 8.

You can also dispense with the twin \ thing here in VBA-land.

See also https://docs.microsoft.com/en-us/office/client-developer/excel/how-to-access-dlls-in-excel

Lastly, make sure you use a 32-bit DLL for 32-bit VBA, and a 64-bit DLL for 64-bit VBA.

So many websites in their DECLARE statements have the handle for LoadLibrary and return of GetProcAddress as Long instead of LongPtr.

Problem is that the information is stale - the code was never updated to reflect the post-Excel 2009 state of VBA.



来源:https://stackoverflow.com/questions/43426323/calling-getprocaddress-from-vba-always-returns-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!