在Excel VBA中使用C ++ DLL [英] Using C++ DLL in Excel VBA
问题描述
我从 https创建了 MathFuncsDll.dll
://msdn.microsoft.com/de-de/library/ms235636.aspx 没有问题.我也可以在其他C ++项目中使用数学函数.
I created the MathFuncsDll.dll
from https://msdn.microsoft.com/de-de/library/ms235636.aspx without issues.
I can use the math functions in a different C++ project also without issues.
现在,我想在Excel VBA中使用这些功能.我试过了:
Now I want to use these functions in Excel VBA. I tried:
Public Declare Function DLL_Import_Add Lib "C:\Users\User\Desktop\MathFuncsDll.dll" Alias "Add" (ByVal a As Double, ByVal b As Double) As Double
Sub test()
MsgBox DLL_Import_Add(2.1, 3.3)
End Sub
但是我收到一个运行时错误'453'
找不到DLL入口点.
But I am receiving a Run-time error '453'
The DLL entry point cannot be found.
我该如何解决这个问题?
How can I solve that problem?
MathFuncsDll.h:
MathFuncsDll.h:
// MathFuncsDll.h
#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport)
#else
#define MATHFUNCSDLL_API __declspec(dllimport)
#endif
namespace MathFuncs
{
// This class is exported from the MathFuncsDll.dll
class MyMathFuncs
{
public:
// Returns a + b
static MATHFUNCSDLL_API double Add(double a, double b);
// Returns a - b
static MATHFUNCSDLL_API double Subtract(double a, double b);
// Returns a * b
static MATHFUNCSDLL_API double Multiply(double a, double b);
// Returns a / b
// Throws const std::invalid_argument& if b is 0
static MATHFUNCSDLL_API double Divide(double a, double b);
};
}
MathFuncsDll.cpp:
MathFuncsDll.cpp:
// MathFuncsDll.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "MathFuncsDll.h"
#include <stdexcept>
using namespace std;
namespace MathFuncs
{
double MyMathFuncs::Add(double a, double b)
{
return a + b;
}
double MyMathFuncs::Subtract(double a, double b)
{
return a - b;
}
double MyMathFuncs::Multiply(double a, double b)
{
return a * b;
}
double MyMathFuncs::Divide(double a, double b)
{
if (b == 0)
{
throw invalid_argument("b cannot be zero!");
}
return a / b;
}
}
推荐答案
我认为从VB程序调用C ++库时,您知道自己在做什么,我指的是调用约定.
问题是C ++名称被被弄乱了.
The problem is that C++ names are mangled.
如果您查看导出的函数名称(例如,使用 dumpbin/EXPORTS MathFuncsDll.dll
,则它们类似于以下内容:
If you take a look at the exported functions names (for example with dumpbin /EXPORTS MathFuncsDll.dll
, they are something like these:
ordinal hint RVA name
1 0 00001000 ?Add@MyMathFuncs@MathFuncs@@SAHHH@Z
2 1 00001030 ?Divide@MyMathFuncs@MathFuncs@@SAHHH@Z
3 2 00001020 ?Multiply@MyMathFuncs@MathFuncs@@SAHHH@Z
4 3 00001010 ?Subtract@MyMathFuncs@MathFuncs@@SAHHH@Z
我的输出将与您的输出不同,但是足以表明没有像 Add
这样的简单名称.
My output will differ from yours, but it suffices to show that there are no simple names like Add
.
通常,使用修饰符 extern"C"
可以避免这种混乱情况.
使用Microsoft编译器,类成员名称似乎总是被修饰,因此在这里是没有用的.
Usually you avoid this mess with the use of the modifier extern "C"
.
With Microsoft compiler, class memebers names seem to be always mangled, so it is useless here.
您可以通过以下四种方法解决此问题:
You can workaround this in four ways:
1.定义一个 DEF
文件来重命名功能
LIBRARY MathFuncsDll
EXPORTS
Add=?Add@MyMathFuncs@MathFuncs@@SAHHH@Z
...
2.在您的VBA声明中使用正确的别名
Public Declare Function DLL_Import_Add Lib "C:\Users\User\Desktop\MathFuncsDll.dll" Alias "?Add@MyMathFuncs@MathFuncs@@SAHHH@Z" (ByVal a As Double, ByVal b As Double) As Double
3.按顺序导入,使用类似 Alias#1"
3. Import by ordinal, using something like Alias "#1"
Public Declare Function DLL_Import_Add Lib "C:\Users\User\Desktop\MathFuncsDll.dll" Alias "#1" (ByVal a As Double, ByVal b As Double) As Double
4.定义调用其等效项的全局存根函数
extern "C" MATHFUNCSDLL_API double Add(double a, double b)
{
return MathFuncs::MyMathFuncs::Add(a, b);
}
并导出它们.
这都不是完美的,请记住,损坏的名称是特定于编译器的,如果使用它们并更改/更新编译器,则事情可能会崩溃.
None of this is perfect, keep in mind that mangled names are compiler specific, if you use them and change/update the compiler, things may break up.
除非您使用 DEF 文件(同样需要重新命名的文件),否则序号也不固定.
Also ordinals are not fixed, unless you use a DEF file (that again need the mangled name).
最后一个选项可用于更改调用约定,并且不会更改原始函数的导出方式,从而允许访问C ++和非C ++程序.
The last option is useful to change calling convention and won't change the way the original functions are exported, thus allowing access to both C++ and non C++ programs.
这篇关于在Excel VBA中使用C ++ DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!