从C源代码编译DLL。 无法在Excel VBA中使用。 文件未find错误

我写了一个C函数(对于64位的一些按位操作),我想在我的Excel VBAmacros中使用该函数。 我使用这里描述的步骤来创build一个使用cygwin(64位)的DLL文件。

以下是我用来创build实际的dll的命令:

gcc -c tokenid.c gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias 

tokenid.c中的函数声明如下所示:

 extern __declspec(dllexport) unsigned long long __stdcall calculateToken(double epoch_time, LPSTR enb_market[], LPSTR file_type[], long source) 

我已经testing了一个小型的C程序的DLL,它工作正常。 这是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和test.c(以及所有其他中间文件)位于相同的目录(cygwin的默认目录)。

然后,我复制了tokenid.dll(cygwin1.dll – 依赖关系walker表示缺less)到存储macros的工作簿的文件夹中。 这是我写的testingmacros:

 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 

但是excel无法finddll。 每当我尝试运行macros时,我都会得到

运行时错误48.找不到文件

我已经尝试了以下内容:

  • 我试图硬编码的path,但它的故事。
  • 我将当前工作目录的path添加到系统path中,但无济于事。
  • 依赖Walker没有发现任何缺less的DLL。 cygwin1.dll(它表示之前缺less)从当前工作目录中提取。

有人能指点我正确的方向吗? 我在这里做错了什么?

编辑:我使用Windows 7(64位),Office 2013和Cygwin 64位。

另外,注意到一个奇怪的事情。 如果我将dll文件放在system32文件夹中并对代码中的path进行硬编码,则错误代码将从48更改为53.无论我做了什么,错误代码始终为48。 不知道为什么!

解决了:

我使用以下语句编译了dll:

 i686-w64-mingw32-gcc -c tokenid.c i686-w64-mingw32-gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias -static-libgcc 

我在64位Windows上,但Office仍然是32位。

我还将VBA中的声明的返回types更改为Currency,因为我从C程序中返回了一个64位值。

1-你必须将你的函数标记为extern以防止重命名它(如果有的话)。
2-你的函数返回long不了double
3-不需要将扩展​​名(即.dll )放入声明中。

 extern __declspec(dllexport) unsigned long long __stdcall calculateToken(double epoch_time, LPSTR enb_market[], LPSTR file_type[], long source) { return 10; } 

和:

 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 

这是为我工作(Windows 7的32位+办公室2010年+ minGW)。
如果问题仍然存在,请尝试以pipe理员身份运行Excel。
编辑
我有和Cygwin一样的错误, 经过一番研究,我得到了解决办法:
您必须使用交叉编译器(来自Cygwin),如下所示:
1-对于Windows 64位:

 x86_64-w64-mingw32-gcc -c tokenid.c x86_64-w64-mingw32-gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias 

2-对于Windows 32位:

 i686-w64-mingw32-gcc -c tokenid.c i686-w64-mingw32-gcc -shared -o tokenid.dll tokenid.o -Wl,--add-stdcall-alias 

据我所知:在Cygwin上用gcc构build的DLL只能通过用Cygwin上的gcc构build的EXE来链接。