2014-01-09 92 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