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:
- I tried hardcoding the path but its the same story.
- I added the path of the current working directory to the system path but to no avail.
- Dependency Walker does not find any missing dll. The cygwin1.dll (which it said was missing earlier) is picked up from the current working directory.
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.