I want to do what the title says. This has been discussed before (How to create dll using gcc compiler/Mingw for visual basic?), but these posts are 10 years old. I was writing Excel/VBA macros at that time without difficulty, but now I want to update them to 64 bit Windows. I've also switched compilers since then. I have had no trouble creating DLLs with gcc
or gfortran
that are called by gcc
or Python
. It is difficult to understand the compatibility issues, because you don't know when an article was written and whether it is still valid in the 64 bit world. You may ding me for rehashing this old subject, but maybe others have a similar problem. I have also found an excellent article (https://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/). I have tried to follow both of these, but can't get anything working in an Excel spreadsheet. Maybe I've made a mistake that will be obvious to someone. Here is the function, code.c
:
__declspec(dllexport) int __stdcall sqint(int x){
return x * x;
}
I build the DLL with:
gcc code.c -shared -o code.dll -s -Wl,--subsystem,windows,--kill-at,-Map=code.map
The code.map file and the objdump utility, both show the function, e.g. here are a few lines from objdump -p code.dll
:
[Ordinal/Name Pointer] Table
[ 0] sqfloat
[ 1] sqint
where sqfloat
is a similar code with doubles. The map file also shows references to libraries, like:
/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/../../../../lib/libcygwin.a
Next, I declare it in VBA with:
Declare PtrSafe Function sqint Lib "C:\Cwin\mix\code.dll" (ByVal x As Long) As Long
A visual basic long and gcc int should both be 4 bytes. I should be able to call the function directly, but I tried putting it inside another function during debugging. With the VBA debugger, I can see the value being passed to the function, but I get nothing other than the dreaded #VALUE!
. If you see what I've done wrong, I'd appreciate hearing from you.
Update 7/2/2020: I've made another stab at this problem with limited success. I believe the DLL I was creating was not 64 bit. I thought this would be the default. The build is now like:
gcc code.c -Wa,-march=generic64 -shared -o code.dll -s -Wl,--subsystem,windows,--kill-at,-Map=code.map
Following the posts at how to test DLL, using file code.dll
gives:
code.dll: PE32+ executable (DLL) (GUI) x86-64 (stripped to external PDB), for MS Windows
The sqfloat function now returns a correct result, but then eventually Excel craps out and closes. The sqint function returns 2*2 = 1. I tried using Integer
instead of long
, but no change. Did MSVBA change the definition of long?
So the current status is I occasionally get a result, but the macro kills Excel.