【发布时间】:2015-07-27 16:54:51
【问题描述】:
我已经用 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。不知道为什么!
已解决:
我使用以下语句编译了 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 位值。
【问题讨论】: