C++ DLL原因“;“Microsoft Excel已停止工作”;但它在Win32控制台应用程序中运行良好
这将是一篇很长的文章,但我不确定需要什么信息来正确解释这个问题。我有一个C++的DLL,我想从Excel调用。每当我调用其中一个函数时,它都会导致Excel崩溃,并显示“Microsoft Excel已停止工作” 头文件:C++ DLL原因“;“Microsoft Excel已停止工作”;但它在Win32控制台应用程序中运行良好,c++,vba,visual-studio-2012,dll,C++,Vba,Visual Studio 2012,Dll,这将是一篇很长的文章,但我不确定需要什么信息来正确解释这个问题。我有一个C++的DLL,我想从Excel调用。每当我调用其中一个函数时,它都会导致Excel崩溃,并显示“Microsoft Excel已停止工作” 头文件: #include <string> namespace XYZ_ProjectWise { class FileOperator { public: static __declspec(dllexport) long __
#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);
};
}
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调用<代码>初始化()/C++ >崩溃,但是VBA调用到
在VBA端,您将字符串参数声明为按值字符串,VBA封送拆收器将转换为char*。你已经这样做了,所以你需要的唯一改变是C++代码。我不确定,但是我注意到一个字符串,另一个取数字。VBA知道std::string是什么吗?它不知道,值得注意的是它可以工作。就这样!现在工作很好。有趣的是,我不希望封送员缺少
std::string
,但能够提供char*
。在哪里可以找到VBA编组程序提供的C++类的列表?整数类型、浮点类型、指向这些简单类型的指针、包含这些简单类型的结构。请记住,std::string仅在其接口中标准化。实现方式各不相同。所以VBA不能提供有许多不同形式的东西;你会期望WCHAR*
@MSalters我不认为旧版本的经典VB非常,呃,支持Unicode。
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