3

I'm trying to use a C / C++ static function in Excel / VBA through a DLL.

I'm getting an exception when debugging in VS17, and I suspect it's an issue with the way the argument is passed (it's a double)

Exception thrown at 0x00007FFA28BBA14F (kernel32.dll) in EXCEL.EXE: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

here's my C code:

test.h

extern "C" __declspec(dllexport) double get_sum_cpp(double x);

test.cpp

double WINAPI get_sum_cpp(double x)
{
   double res = x + x;
   return res;
}

declaration in VBA:

Declare PtrSafe Function get_sum_cpp Lib "C:\Users\bbi\source\repos\Test\x64\Debug\Test.dll" (ByVal my_var As Double) As Double

test code in VBA:

Sub testSum()

    Dim A As Double
    Dim Asum As Double

    A = 5

    Asum = get_sum_cpp(A)

end sub

I'm running 64 bits excel, and the dll is compiled in debug mode 64 bits.

I have many more issues with the overall development (for example any function with more than one argument will crash excel entirely), but this is the smallest "unit test" I could get too.

I feel it's an issue with the way the VBA double argument is passed to the DLL function, (stack misalignment ?), but I can't figure out how to set it right. When debugging in VS17, the exception occurs before I reach the line "double res = x + x", so I suspect it's happening at the function declaration, so when the double argument is passed - so an issue with casting - again maybe stack misalignment ?

my exports seem OK - checked with dumpbin / EXPORTS. The function is found and eventually returns.

Any idea ?

Bastien
  • 1,537
  • 2
  • 10
  • 19

2 Answers2

2

I have successfully ran your code exactly without any problem on my computer.

My VBA script:

Private Declare PtrSafe Function get_sum_cpp Lib "D:\Codes\VC\TestVBA\x64\Debug\Dll2.dll" (ByVal my_var As Double) As Double

Sub testSum()

    Dim A As Double
    Dim Asum As Double

    A = 5

    Asum = get_sum_cpp(A)

    MsgBox "Val is: " & Asum
End Sub

and your C++ code. I have tested both with your code and using __declspec(dllexport) and definition file. Both works. I also have tested with/without DLL runtime library. Still works.

I have used VS2019, Excel 2019. If they are not same version, make sure you are using /MT not /MTd for non-DLL runtime libraries though.

Afshin
  • 8,839
  • 1
  • 18
  • 53
-1

I had the same exceptions and the same question. I came to conclusion that it's normal behaivior for Excel causing no issues or leaks (you can ignore these messages in debug window), happening when parameters are passed as value (byval). It's a bit strange, but it seems Excel (or Kernel32) tries to test / access the memory address taken from variable's value. In my case I passed Boolean byval and Excel tried to access FFFFFFFF address for True value and 00000000 for False...

This exception disappears when parameter is passed by reference (which is default option for VBA)...

I hope it helps.

P.S. for those who have doubts. The following simple code helps to reproduce mentioned exception (visible only in VS debug) in the line with 'FreeLibrary'

Private Declare PtrSafe Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare PtrSafe Function LoadLibraryA Lib "kernel32" (ByVal lpLibFileName As String) As Long

Sub Test()
  Dim lA As Long
  lA = LoadLibraryA("user32.dll")
  lA = FreeLibrary(lA) '<- Here comes an exception report in VS debug window
End Sub

LoadLibrary does not rise any exceptions, as string is passed as a pointer to the copy (byval) of BSTR in memory, allocated by Excel himself, thus causing no issues if tested / accessed...

P.P.S. Well, it was alredy discussed here: Problem passing parameters from Excel VBA x64 to C++ dll x64

Needle
  • 1
  • 1