gpt4 book ai didi

c++ - DLL 导致 "Microsoft Excel has stopped working"但它在 Win32 控制台应用程序中工作正常

转载 作者:行者123 更新时间:2023-11-30 02:51:38 36 4
gpt4 key购买 nike

这将是一篇很长的文章,但我不确定需要哪些信息才能正确解释这个问题。我有一个要从 Excel 调用的 C++ DLL。每当我调用其中一个函数时,它都会导致 Excel 崩溃并显示“Microsoft Excel 已停止工作”。

头文件:

#include <string>

namespace XYZ_ProjectWise
{
class FileOperator
{
public:
static __declspec(dllexport) long __stdcall initialize(std::string dbName);
static __declspec(dllexport) long __stdcall openDoc(long projectID,long docID);
};
}

initialize()的函数代码:

long FileOperator::initialize(string dbName)
{
LPCWSTR user=L"";
LPCWSTR pwd=L"";
LPCWSTR schema=L"";
std::wstring sTemp=std::wstring(dbName.begin(),dbName.end());
LPCWSTR dbName_L=sTemp.c_str();
bool resultInit=aaApi_Initialize(AAMODULE_ALL);
bool resultLogin=aaApi_Login(AAAPIDB_UNKNOWN,dbName_L,user,pwd,schema);
return 0;
}

dumpbin/exports 的输出:

?initialize@FileOperator@XYZ_ProjectWise@@SGJV?$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z

VBA 中的声明:

Private Declare Function initialize Lib "C:\Program Files
(x86)\Bentley\ProjectWise\bin\XYZ_ProjectWiseDLL.dll" _
Alias "?initialize@FileOperator@XYZ_ProjectWise@@SGJV?$basic_string@DU?
$char_traits@D@std@@V?$allocator@D@2@@std@@@Z" _
(ByVal dbName As String) As Long

它在 VBA 中的调用方式:

Public Sub testDLL()

Dim result As Long
result = initialize("ABC.DEF.GHI.com:PWOPPID_XYZ")

End Sub

奇怪的是,如果我在 openDoc() 函数中包含 initialize() 函数代码,并使用 dbName 硬编码,并按如下方式自行调用 openDoc():

long __stdcall FileOperator::openDoc(long projectID,long docID)
{

LPCWSTR dbName=L"ABC.DEF.GHI.com:PWOPPID_XYZ";
LPCWSTR user=L"";
LPCWSTR pwd=L"";
LPCWSTR schema=L"";
bool resultInit=aaApi_Initialize(AAMODULE_ALL);
bool resultLogin=aaApi_Login(AAAPIDB_UNKNOWN,dbName,user,pwd,schema);

long resultOpen=aaApi_OpenDocument(projectID,docID,false);
return resultOpen;
}
}

VBA调用:

Private Declare Function openDoc Lib "C:\Program Files 
(x86)\Bentley\ProjectWise\bin\XYZ_ProjectWiseDLL.dll" _
Alias "?openDoc@FileOperator@XYZ_ProjectWise@@SGJJJ@Z" _
(ByVal projectID As Long, ByVal docID As Long) As Long

Public Sub testDLL()

Dim result As Long
result = openDoc(1799,29)

End Sub

那么,为什么 VBA 调用 initialize() 会崩溃,而 VBA 调用 openDoc() 中的相同代码却工作正常?

最佳答案

明显的问题是 C++ 代码使用了对互操作无效的 C++ 类。 VBA 编码器根本无法提供 std::string。仅使用简单的 POD 类型进行互操作。

在 C++ 方面,对于字符串参数,接收指向空终止字符数组的指针,const char*。由于 std::string 有一个接受 const char* 的构造函数,因此很容易根据您的需要调整这样的参数。

在 VBA 端,您将字符串参数声明为按值字符串,VBA 编码器将转换为 char*。您已经这样做了,所以您唯一需要的更改是 C++ 代码。

关于c++ - DLL 导致 "Microsoft Excel has stopped working"但它在 Win32 控制台应用程序中工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19574301/

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