我在C中编写了一个函数(对于64位的一些按位操作),我想在我的excel vba宏中使用该函数 . 我使用steps described here使用cygwin(64位)创建DLL文件 .
以下是我用来创建实际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)
我用一个小的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表示它丢失了)复制到存储宏启用的工作簿的文件夹中 . 这是我写的测试宏:
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无法找到dll . 每当我尝试运行宏时,我都会得到
运行时错误48.找不到文件
我已经尝试过以下方法:
-
我试过硬编码路径,但它的故事是一样的 .
-
我将当前工作目录的路径添加到系统路径但无济于事 .
-
Dependency Walker没有找到任何丢失的dll . 从当前的工作目录中选取了cygwin1.dll(它说之前没有丢失) .
有人能指出我正确的方向吗?我在这做错了什么?
编辑:我使用的是Windows 7(64位),Office 2013和Cygwin 64位 .
另外,注意到一个奇怪的事情 . 如果我将dll文件放在system32文件夹中并对代码中的路径进行硬编码,则错误代码将从48更改为53.无论我做什么,错误代码始终为48 . 不知道为什么!
Solved:
我使用以下语句编译了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中声明的返回类型更改为Currency,因为我从C程序返回64位值 .
1 回答
1-您必须将您的功能标记为
extern
以防止重命名(如果有) .2-你的函数返回
long
而不是double
.3-无需在声明中加入扩展名(即
.dll
) .和:
这对我有用(Windows 7 32位办公室2010 minGW) .
如果问题仍然存在,请尝试以管理员身份运行Excel .
EDIT
我遇到了与我尝试Cygwin时相同的错误;经过一番研究,我得到了解决方案:
你必须使用交叉编译器(来自Cygwin),如下所示:
1- for windows 64 bit:
2-为Windows 32位:
据我所知:在Cygwin上使用gcc构建的DLL只能通过在Cygwin上使用gcc构建的EXE进行链接 .