我想用C ++编译DLL,然后从VBA调用库。我在windows32位上做了这个。但我想复制这样的练习,因为我在工作中使用Windows 64位。鉴于这一事实,我下载了mingw 64。
我的例子:
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
extern "C"
{
int DLL_EXPORT __stdcall add2(int num);
int DLL_EXPORT __stdcall mult(int num1, int num2);
}
#endif // __MAIN_H__
的main.cpp
#include "main.h"
int DLL_EXPORT __stdcall add2(int num)
{
return num + 2;
}
int DLL_EXPORT __stdcall mult(int num1, int num2)
{
int product;
product = num1 * num2;
return product;
}
当我编译dll时,我传递了这个链接器选项:
Wl,--add-stdcall-alias
和/或
Wl,--kill-at
我还生成了.def文件,如下所示:
EXPORTS
add2 @1
mult @2
我期待一个看起来像这样的.def文件(就像在我的32位PC中一样):
EXPORTS
add2 @1
mult @2
add2 = add2 @1
mult = mult @2
然后我像这样调用VBA中的dll和函数:
Public Declare PtrSafe Function add2 _
Lib "C:\MyPath\dll.dll" _
(ByVal num As Long) As Long
问题是:可以从VBA编辑器调用这些函数并给出正确的结果,但是当从Excel工作表调用时,它们会抛出一些其他数字(传递的参数的地址??)。如果我在Excel中尝试从VBA调用该函数,那么VBA会抛出一个错误(堆栈空间不足)。
当我使用mingw4.7 32位时,此问题不存在。问题是当我使用mingw 4.6.3 64bit进行编译时(我已经安装了mingw4.7 64位,但我在互联网上发现人们说4.6.3更稳定)
我还注意到.def文件看起来与上面的文件完全相同,即使我没有通过我的链接器选项。
有人可以帮忙吗?发生了什么?是mingw64或vba / Excel feiling?或者是我的mingw64配置?
更新 .... 好的,我发现这个网站:https://sites.google.com/site/jrlhost/links/excelcdll#array并在VBA中使用和itermediate函数解释,我的函数add2从工作表中工作。
Public function fromWorksheetAdd2 ( dim x as Long) as Long
fromWorksheetAdd2 = add2(x)
end function
然后我可以在工作表中使用fromWorksheetAdd2,在VBA使用Add2。然而,这种方法有点乏味。希望有人能以优雅的方式提供帮助。
答案 0 :(得分:0)
查看您的参数。
VBA中的长是64位(8字节)。在C ++方面,int的大小是sizeof(int)的大小,在你正在使用的环境中可能超过4个字节。
您必须保证在VBA和C ++之间发送和返回的类型大小完全相同,否则最终会导致堆栈损坏。