【问题标题】:Calling C++ DLL from VBA, getting "Access violation writing location" error从 VBA 调用 C++ DLL,出现“访问冲突写入位置”错误
【发布时间】:2014-07-02 10:01:47
【问题描述】:

我有一个 Excel VBA 项目,我试图从 Visual Studio 2013 输出的 C++ DLL 调用函数。我添加了对 DLL 的引用。当我尝试在 VS 调试器中运行它时,它附加到我调用 DLL 函数的 Excel 实例:

Private pw_ As Long

Private Sub class_initialize()
   pw_ = ProjectWiseAPI.CreateProjectWise(True)
End Sub

我收到此错误:

Unhandled exception at 0x0EBE8536 (libProjectWise.dll) in EXCEL.EXE: 
OxC0000005: Access violation writing location 0xFFFFFFFF.

这个函数中断了:

PWAPI CreateProjectWise(LPVOID *obj, VARIANT_BOOL showErrors) {
    *obj = new XYZ_ProjectWise::ProjectWise(showErrors != FALSE);
    return S_OK;
}

特别是在*obj 分配行上。

另外,当我只使用 Excel 文件本身而不是 VS 时,当我编译 VBA 项目时,我收到此错误:

File not found: T:\location\of\dll\libProjectWise.dll

即使我已将 DLL、EXP、ILK、LIB、MAP 和 PDB 文件复制到 T:\location\of\dll 文件夹,并且我的 ODL 文件包含以下行:

[
   dllname("T:\location\of\dll\libProjectWise.dll")
]

我对这一切感到很困惑。这个 API 不是我写的,对 C++ 以及如何在 Visual Studio 中开发也只是粗略的了解。原始开发者不可用。

编辑: 这是CreateProjectWise函数的ODL代码:

[
        helpstring("Gets an instance of the API object"),
        entry("_CreateProjectWise@8")
]
HRESULT __stdcall CreateProjectWise([in] VARIANT_BOOL showErrorMessage, [out, retval] long *obj);

【问题讨论】:

  • 您需要显示更多 IDL,尤其是 [out, retval] 等注释。
  • @BenVoigt,为此函数添加了 ODL。
  • 比较 ODL 和函数体时发现任何可疑之处?比如参数名称和类型与返回类型不匹配?
  • ODL 括号中的部分错误,添加了正确的部分

标签: c++ excel vba dll visual-studio-2013


【解决方案1】:

该 C++ 签名不可能匹配该调用。 C++有两个参数,调用只有一个。还有a [retval] attribute is allowed only on the last parameter,所以showErrors不可能是从VBA传递的,而obj是存储到pw_中的返回值的缓冲区。

查看函数的ODL,很明显参数顺序与定义相反。因此,来自 VBA 的 showErrorMessage 参数在 C++ 中被视为指针,其结果是可以预见的。

MIDL 编译器在处理 ODL 时会创建一个头文件。对#include这个头文件在C或C++代码中的实现非常有帮助,这样编译器就可以自动捕捉到这样的问题。

【讨论】:

  • 我颠倒了 PWAPI 定义中的参数,但现在当我尝试从 VS 调试器运行它时,我得到了Can't find DLL entry point _CreateProjectWise@8
  • @sigil: PWAPI 定义?类似于#define PWAPI HRESULT __stdcall __declspec(dllexport) 的那个?
  • 不,我的意思是我在原始问题中包含的PWAPI CreateProjectWise(LPVOID *obj, VARIANT_BOOL showErrors)。我把LPVOID *obj放在最后,结果得到Can't find DLL entry point
  • @sigil:啊,这就是CreateProjectWise 的定义。这只是 32 位编译,对吧?使用dumpbin /exports比较参数重排前后导出了哪些函数。
  • 问题是我还没有反转头文件libProjectWise.h中函数声明中的参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多