gpt4 book ai didi

c++ - 在 Excel VBA 中使用 C++ DLL

转载 作者:搜寻专家 更新时间:2023-10-31 00:10:56 26 4
gpt4 key购买 nike

我从 https://msdn.microsoft.com/de-de/library/ms235636.aspx 创建了 MathFuncsDll.dll没有问题。我可以在不同的 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

但我收到一个运行时错误“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);
};
}

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++ 库时,我指的是 calling convention .


问题是 C++ 名称是 mangled .

如果您查看导出的函数名称(例如使用 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

我的输出将与您的不同,但足以表明没有像 Add 这样的简单名称。

通常使用修饰符 extern "C" 可以避免这种困惑。
使用 Microsoft 编译器,类成员名称似乎总是被破坏,因此在这里没有用。

您可以通过四种方式解决此问题:

<强>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"

的东西
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。定义调用其等效项的全局 stub 函数

extern "C" MATHFUNCSDLL_API double Add(double a, double b)
{
return MathFuncs::MyMathFuncs::Add(a, b);
}

并导出它们。

这些都不是完美的,请记住,损坏的名称是特定于编译器的,如果您使用它们并更改/更新编译器,事情可能会崩溃。

此外,序数也不是固定的,除非您使用 DEF 文件(同样需要错位的名称)。

最后一个选项可用于更改调用约定,不会更改原始函数的导出方式,因此允许访问 C++ 和非 C++ 程序。

关于c++ - 在 Excel VBA 中使用 C++ DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668544/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com