I have written a function in C (for some bitwise operations on 64-bit) and I want to use that function in my excel vba macro. I used steps described here to create a DLL file using cygwin (64-bit).
Here are the commands I used to create the actual dll:
gcc -c tokenid.c
gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias
The function declaration inside tokenid.c is like this:
extern __declspec(dllexport) unsigned long long __stdcall calculateToken(double epoch_time, LPSTR enb_market[], LPSTR file_type[], long source)
I have tested the dll with a small c program and it works fine. Here's the source code for test.c:
#include<stdio.h>
#include<windows.h>
//typedef unsigned long long (__stdcall *calcToken)(double, char[], char[], long);
typedef unsigned long long (__stdcall *calcToken)(double, LPSTR, LPSTR, long);
int main(){
HANDLE ldll;
calcToken calculateToken = NULL;
ldll = LoadLibrary("tokenid.dll");
if(ldll > (void*)HINSTANCE_ERROR){
FARPROC fptr = GetProcAddress(ldll, "calculateToken");
calculateToken = (calcToken)(fptr);
char market[] = {'A','B','C'};
char usage[] = {'D','E','F'};
printf("%llu", calculateToken(1431680395, market, usage, 90));
} else {
printf("ERROR.");
}
}
tokenid.c and test.c (and all other intermediate files) are in the same same directory (cygwin's default).
Then I copied the tokenid.dll (cygwin1.dll - dependency walker said it was missing) to the folder where the macro enabled workbook is stored. Here's the test macro I wrote:
Option Explicit
Public Declare Function calculateToken Lib "tokenid" (ByVal epoch_time As Double, ByVal market As String, ByVal usageType As String, ByVal source_id As Long) As Currency
Public Sub test()
'*****************
'Declare Variables
'*****************
Dim market As String, usageType As String
Dim epoch As Double
Dim source_id As Long
Dim tokenid As Currency
market = "ABC"
usageType = "DEF" 'file type in the C program
epoch = 1431680395
source_id = 90
tokenid = calculateToken(epoch, market, usageType, source_id)
Debug.Print tokenid
End Sub
But excel is unable to find the dll. Whenever I try to run the macro, I get
Run-time error 48. File not found
I have already tried the following:
Can someone point me to the right direction? What am I doing wrong here?
EDIT: I am using Windows 7 (64-bit), Office 2013 and Cygwin 64-bit.
Also, noticed one weird thing. If I place the dll file in system32 folder and hardcode the path in the code, the error code changes from 48 to 53. The error code is always 48 no matter what else I do. Not sure why!
Solved:
I compiled the dll using the following statements:
i686-w64-mingw32-gcc -c tokenid.c
i686-w64-mingw32-gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias -static-libgcc
I was on 64-bit Windows but Office was still 32-bit.
I also changed the return type of the declaration in VBA to Currency since I was returning a 64-bit value from the C program.
1- you must mark your function as extern to prevent renaming it (if any).
2- your function returns long not double.
3- no need to put the extension (i.e .dll) in the declaration.
extern __declspec(dllexport) unsigned long long __stdcall calculateToken(double epoch_time, LPSTR enb_market[], LPSTR file_type[], long source)
{
return 10;
}
and:
Public Declare Function calculateToken Lib "tokenid" (ByVal epoch_time As Double, ByVal market As String, ByVal usageType As String, ByVal source_id As Long) As Long
this is worked for me (windows 7 32 bit + office 2010 + minGW).
if problem still exists, try to run Excel as administrator.
EDIT
I have got the same error that you had got when I tried Cygwin; after some research I have got the solution:
you must use the cross-compiler (from Cygwin) as following:
1- for windows 64 bit:
x86_64-w64-mingw32-gcc -c tokenid.c
x86_64-w64-mingw32-gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias
2- for windows 32 bit:
i686-w64-mingw32-gcc -c tokenid.c
i686-w64-mingw32-gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias
As I understood: DLLs built with gcc on Cygwin can only be linked by EXE built with gcc on Cygwin.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With