【问题标题】:Argument not taken into account when using C++ dll in excel在 excel 中使用 C++ dll 时未考虑参数
【发布时间】:2016-03-08 00:27:13
【问题描述】:

您好,我正在尝试创建一个用于 Excel 的简单 C++ dll。

这是我所做的:

.cpp 文件:

    double _stdcall Test(double z)
{
    return z+2.0;
}

.def 文件:

LIBRARY
EXPORTS
Test

在视觉工作室中: 项目属性>配置属性>命令>“路径/EXCEL.EXE”

配置管理器 > 平台 > x64

在 VBA 中:

Declare PtrSafe Function Test Lib _
"Path\MyDLL" (ByVal z As Double) As Double

但是当我在 Excel 中调用 Test(2) 时,它返回 2,而不是 4。似乎参数总是被视为 0(实际上,如果我在调用函数时在文件中输出 z 的值,它是2.122e-314)。

任何意见将不胜感激。

谢谢

编辑 1: 如果我将参数和返回值更改为 int 并在 VBA 中更改为 Long,Test(2) 将返回 3。

有人知道为什么 int 的参数是 1 吗?

【问题讨论】:

  • 一切都适合我。您是否记得将模块定义文件设置为您的 .def 文件?这是什么Project Properties > Configuration properties > Command > "Path/EXCEL.EXE"。我没有这样的选择。
  • 如果我不放这个,我会收到以下错误:“path/MyDLL.dll”不是有效的 Win32 应用程序。问题是 def 文件可能工作正常,因为函数被调用,只是 Excel 参数没有被考虑
  • 您的 C++ 编译器不知道函数正在导出。所以它期望参数以不同的方式传递,浮点是用 SSE 指令完成的,参数是通过 XMM0 寄存器传递的。然而,Excel 假定参数应该以传统方式在 FPU 寄存器 ST0 中传递。将__declspec(dllexport)放在函数前面即可解决问题。
  • 您好,感谢您的意见,但没有解决问题。

标签: c++ excel dll


【解决方案1】:

道歉:本可以将其作为评论发布,但还不能:

首先:您的函数可能会导出为 C++ 错位名称。 使用 extern "C" 来防止名称混淆。还有其他方法可以做到这一点,但这是最直接的。但是,如果成功调用了 Test 函数,我不确定这是否是问题所在。

使用 extern "C" 你的 C 函数看起来像这样。

extern "C"
double _stdcall Test(double z)
{
    return z+2.0;
}

第二:您确定您选择的是正确的 DLL,而不是缺少修复程序的旧 DLL?尝试在源代码和 Excel VBA 包装器中将函数名称更改为更具体的名称。

第三:如果您不是在 64 位 Excel 系统上运行,请从 VB 中的函数规范中删除 PtrSafe 声明并重新编译为 32 位。

第四:不要尝试直接从 Excel 单元格调用您的 DLL。将函数包装在 VBA 中(示例如下)或使用 CALL 函数。

下面的代码是一个如何包装一个VBA单元函数的例子。

Public Function CellFunction_Test(x As Double) As Double
'' Tells excel to call this function only if the inputs change
'' and not on every recalculation
Application.Volatile False

'' Set an error handler, good practise for more complicated functions you might write later
On Error GoTo CellFunction_Test_EH:

'' Call into the DLL
CellFunction_Test = Test(x)
Exit Function

'' Error Handler
CellFunction_Test_EH:
CellFunction_Test = "Error - " & Err.Description
End Function

【讨论】:

  • 您好,感谢您添加您的意见,非常感谢。 1.我添加了外部“C”行。没有改变任何东西。 2.使用新项目再次尝试,所以我确定是的,但仍然没有运气。 3.我正在运行x64 Excel 2013版...我可以在Excel中调试程序,并且确实调用了该函数。但是,就像在 Excel 调用和 C++ 执行之间清理堆栈一样。因为如果按值传递z的值为2e-314,如果我通过引用传递它并给出C++函数参数列表中的地址,则无法读取内存异常。也许这澄清了
  • 您是直接从 Excel 单元格调用此函数(例如 =TEST(2) )还是从 VBA 作为宏或其他函数中的函数调用?
  • 谢谢各位,第四点帮我解决了!非常感谢,但我不知道具体原因...
猜你喜欢
  • 2021-07-20
  • 2018-10-26
  • 1970-01-01
  • 2015-07-13
  • 2023-02-26
  • 2018-11-21
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
相关资源
最近更新 更多