C++ 32位DLL与Excel VBA调用报错Run-time error '49'求助
解决Excel VBA调用C++ DLL出现Run-time error '49'的问题
问题原因
这个错误的核心是调用约定不匹配:
- Visual Studio中C++函数默认使用
__cdecl调用约定,由调用者负责清理栈。 - VBA声明DLL函数时,默认使用
__stdcall调用约定,由被调用函数负责清理栈。 - 无参数的
add2能运行是因为没有参数栈需要平衡,属于侥幸情况,并非正确实现。
解决方案
以下提供两种可行的修复方式:
方式一:修改C++函数为__stdcall调用约定
调整C++代码和导出定义,让函数适配VBA默认的调用约定:
- 更新头文件
simplesum.h:
#pragma once // 指定__stdcall调用约定 double __stdcall add(double x, double y); double __stdcall add2();
- 更新实现文件
simplesum.cpp:
#include "pch.h" #include "simplesum.h" double __stdcall add(double x, double y) { return 10; } double __stdcall add2() { return 1; }
- 更新
simplesum.def文件:__stdcall会给函数名添加修饰后缀(如_add@16),需要在def文件中指定别名映射:
LIBRARY simplesum EXPORTS add=_add@16 // 两个double参数共16字节 add2=_add2@0 // 无参数字节数为0
重新编译DLL后,原VBA声明即可正常工作。
方式二:在VBA声明中指定Cdecl调用约定
若不想修改C代码,可在VBA的Declare语句中添加Cdecl关键字,适配C默认的__cdecl约定:
Option Explicit Declare PtrSafe Function add Lib "C:\DEV\CPP\CPP_DEV\simplesum\Debug\simplesum.dll" _ (ByVal x As Double, ByVal y As Double) As Double Cdecl Declare PtrSafe Function add2 Lib "C:\DEV\CPP\CPP_DEV\simplesum\Debug\simplesum.dll" _ () As Double Cdecl
注:
PtrSafe是为64位Excel兼容设计的,32位环境下保留不影响使用。
修改后直接运行test1和test2即可正常调用。
额外注意事项
- 确保DLL位数与Excel一致:你生成的是32位DLL,需对应使用32位Excel,否则会出现加载错误。
- 调试优先用Release版本DLL:Debug版本含额外调试信息,可能引发兼容性问题。
内容的提问来源于stack exchange,提问作者Leonardo Lima Ferreira
相关产品推荐
相关产品推荐

