Tim*_*gan 2 c++ excel vba excel-vba
我MathFuncsDll.dll从https://msdn.microsoft.com/de-de/library/ms235636.aspx创建了没有问题的.我也可以在不同的C++项目中使用数学函数而不会出现问题.
现在我想在Excel VBA中使用这些功能.我试过了:
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
Run Code Online (Sandbox Code Playgroud)
但是我收到了一个Run-time error '453'无法找到的DLL入口点.
我该如何解决这个问题?
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);
};
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我假设您从VB程序调用C++库时知道自己在做什么,我指的是调用约定.
问题是C++名称被破坏了.
如果您查看导出的函数名称(例如,使用dumpbin /EXPORTS MathFuncsDll.dll,它们是这样的:
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
Run Code Online (Sandbox Code Playgroud)
我的输出与你的输出不同,但它足以表明没有简单的名字Add.
通常你可以通过使用修饰符来避免这种混乱extern "C".
使用Microsoft编译器,类memebers名称似乎总是被破坏,所以在这里没用.
您可以通过以下四种方式解决此问题:
1.定义DEF重命名函数的文件
LIBRARY MathFuncsDll
EXPORTS
Add=?Add@MyMathFuncs@MathFuncs@@SAHHH@Z
...
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
3.按顺序导入,使用类似的东西 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
Run Code Online (Sandbox Code Playgroud)
4.定义调用其等效项的全局存根函数
extern "C" MATHFUNCSDLL_API double Add(double a, double b)
{
return MathFuncs::MyMathFuncs::Add(a, b);
}
Run Code Online (Sandbox Code Playgroud)
并导出它们.
这些都不是完美的,请记住,受损的名称是编译器特定的,如果您使用它们并更改/更新编译器,事情可能会破裂.
除非您使用DEF文件(再次需要损坏的名称),否则序数也不会修复.
最后一个选项对于更改调用约定非常有用,并且不会更改原始函数的导出方式,因此允许访问C++和非C++程序.
| 归档时间: |
|
| 查看次数: |
3525 次 |
| 最近记录: |