2014-01-09 109 views
0

我想用C++编译DLL,然后从VBA中调用库。我已经在windows32位上做了这个。但是因为我在工作中使用了Windows 64位,所以我想复制这样的练习。鉴于这一事实我downdloaded MinGW的64在C++中编译DLL 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工作表中调用函数时,它们会抛出其他数字(传递的参数的地址??)。如果我尝试从VBA调用函数后,我尝试在Excel中,然后VBA引发错误(超出堆栈空间)。

当我使用mingw4.7 32bit时,此问题不存在。问题是当我使用mingw 4.6.3 64bit编译(我安装了mingw4.7 64bit,但是我在互联网上发现人们说4.6.3更稳定)

我也注意到.def文件看起来相同即使我不通过我的链接器选项上面的一个。

任何人都可以帮忙吗?发生了什么?是mingw64或vba/Excel feiling?或者是我的mingw64配置?

UPDATE .... 好,我发现这个网站: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 

然后我可以在VBA的工作表和Add2上使用fromWorksheetAdd2。然而这种方法有点乏味。希望有人可以帮助一个优雅的方法。

回答

0

看看你的参数。

VBA中的长度是64位(8字节)。在C++端,int的大小就是sizeof(int)的大小,在你使用的环境中,这个数量可能是4个字节。

您必须保证在VBA和C++之间发送和返回的类型的大小完全相同,否则可能会导致堆栈损坏。

+0

当您从C或C++创建DLL以供其他语言使用时,最好使用Windows API定义的类型(例如LONG,DWORD)作为参数或返回类型而不是C++ int的参数或返回类型,长,等等。这样,你不会陷入类型不匹配的混乱。 – PaulMcKenzie

+0

我曾尝试在C++和VBA中使用长的长变量都应该由8个字节。我还在C++中使用了LONG,在VBA中使用了Long。但是这些方法都没有解决我的问题。我仍然想知道Wl的效果, - add-stdcall-alias – user1571823