Reputation: 394
I want to compile a DLL in C++ and then call the Library from VBA. I have done this on windows32 bits. But I wanted to replicate such exercise since I use Windows 64 bit at work. Given this fact I downdloaded mingw 64.
My example:
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
extern "C"
{
int DLL_EXPORT __stdcall add2(int num);
int DLL_EXPORT __stdcall mult(int num1, int num2);
}
#endif // __MAIN_H__
main.cpp
#include "main.h"
int DLL_EXPORT __stdcall add2(int num)
{
return num + 2;
}
int DLL_EXPORT __stdcall mult(int num1, int num2)
{
int product;
product = num1 * num2;
return product;
}
When I compile the dll I pass this linker options:
Wl,--add-stdcall-alias
and/or
Wl,--kill-at
I also generate the .def file, which looks like this:
EXPORTS
add2 @1
mult @2
I expected a .def file which looks like this (as in my 32bit PC):
EXPORTS
add2 @1
mult @2
add2 = add2 @1
mult = mult @2
Then I call the dll and the functions from VBA like this:
Public Declare PtrSafe Function add2 _
Lib "C:\MyPath\dll.dll" _
(ByVal num As Long) As Long
The problem is: The functions can be called from VBA editor and gives right results, but when called from an Excel sheet they throw some other number (address of the passed argument??). If I try to call the function from VBA AFTER I tried inside Excel, then VBA throws an error (out of stack Space).
This problem is not present when I use mingw4.7 32bit. The problem is when I compile using mingw 4.6.3 64bit (I had installed mingw4.7 64bit but I found on internet People saying that 4.6.3 is more stable)
I have also noticed that the .def file looks identicall to the one above even if i dont pass my linker options.
Can anybody help? whats happening? is mingw64 or vba/Excel feiling? or is my mingw64 configuration?
UPDATE.... ok I found this site :https://sites.google.com/site/jrlhost/links/excelcdll#array and as explain there by using and itermediate function in VBA, my function add2 Works from the worksheet.
Public function fromWorksheetAdd2 ( dim x as Long) as Long
fromWorksheetAdd2 = add2(x)
end function
then I can use fromWorksheetAdd2 at worksheets and Add2 at VBA. However this approach is kind of tedious. Hope someone can help With an elegant approach.
Upvotes: 0
Views: 3019
Reputation: 35440
Look at your parameters.
A Long in VBA is 64 bits (8 bytes). On the C++ side, the size of an int is whatever sizeof(int) is, which is more than likely 4 bytes in the environment you're using.
You must guarantee that the types you're sending and returning between VBA and C++ are exactly the same size, otherwise you can wind up with stack corruption.
Upvotes: 1