user1571823
user1571823

Reputation: 394

Compiling a DLL in C++ mingw 64

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

Answers (1)

PaulMcKenzie
PaulMcKenzie

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

Related Questions