使用在C ++中创build的DLL从Excel和VBA调用C ++函数

我创build了一个包含名为“koduj”的函数的DLL。 通过在Excel工作表单元格中使用此函数来调用该函数将返回所需的结果。 从VBA调用“koduj”会返回错误的答案。

koduj需要两个参数: string nr_idinteger x1 。 它用ASCII表示法计算nr_id字母的总和,并加上x1 。 计算的总和比返回。

我正在按照这里find的指示。

这是我的.cpp源文件:

 #include<Windows.h> #include<string> using namespace std; //Convert BSTR to wstring for convenience wstring BSTR_to_wstring (BSTR text){ return wstring(text, SysStringLen(text)); } //Calculate sum of letters in ASCII representation int ASCII_sum (wstring ws){ int sum = 0; for (unsigned int i = 0; i < ws.length(); i++) sum += ws[i]; return sum; } //"koduj" function int _stdcall koduj (BSTR nr_id, int & x1){ wstring ws_nr_id = BSTR_to_wstring(nr_id); return ASCII_sum(ws_nr_id) + x1; } 

这是我的VBA函数声明:

 Declare Function koduj _ Lib "<dll_directory_and_full_name>" (ByVal x As String, ByRef y As Integer) As Integer 

通过写作:

 =koduj("aaa";1) 

在工作表单元格里面我得到了想要的结果(292)

debugging这个VBA代码:

 Sub test() Dim a As Integer a = koduj("aaa", 1) End Sub 

揭示错误的结果(a = 24930)

我相信我的C ++代码是好的,因为从Excel的工作表中调用它时可以正常工作。

原因在于即使VBAstring在内部是UTF-16,VB在与外界交stream( Declare d函数,文件input/输出)之前总是将它们转换为ASCII。 所以,当你Declare一个参数As String ,VBA会自动转换string并将其作为ASCII传递出去。 C ++端的匹配参数types应该是LPSTRLPCSTR

如果要在C ++端使用BSTR ,则还需要为该函数创build一个IDL文件,将其编译为一个TLB并从VBA引用TLB,然后VBA才会尊重和使用BSTR

另一个问题是C ++的int转换为VBA的Long

从Excel工作表调用它的原因是显然,Excel会忽略用于string转换的VBA规则 。 我相信这是一个错误。

尝试声明一个很长的时间:Dim a As Long

我从错误的大小猜测,这是错误的数字参数 – 我会尝试更明确地声明参数types在您的testingVBA例程(可能是整数),并接受它作为该特定types的C + +端(签名在这种情况下,简称)。

http://msdn.microsoft.com/en-us/library/office/bb687915(v=office.15).aspx上有关于所有这些的很好的微软文章。

不打算是一个完整的答案,但你的第二个参数的types看起来不正确。

您的DLL函数: int _stdcall koduj (BSTR nr_id, int & x1) x1声明为(可能的)32位整数的引用

您的VBA声明: Declare Function koduj Lib "<dll_directory_and_full_name>" (ByVal x As String, ByRef y As Integer) As Integer声明y作为指向 16位整数的指针

我build议尝试改变VBA声明如下:

Declare Function koduj _ Lib "<dll_directory_and_full_name>" (ByVal x As String, ByVal y As Long) As Long

并且,切换您的DLL函数签名以传递值x1:

int _stdcall koduj (BSTR nr_id, int x1)