Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ DLL原因“;“Microsoft Excel已停止工作”;但它在Win32控制台应用程序中运行良好_C++_Vba_Visual Studio 2012_Dll - Fatal编程技术网

C++ DLL原因“;“Microsoft Excel已停止工作”;但它在Win32控制台应用程序中运行良好

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 __

这将是一篇很长的文章,但我不确定需要什么信息来正确解释这个问题。我有一个C++的DLL,我想从Excel调用。每当我调用其中一个函数时,它都会导致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);
    };
}
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调用到 opdOnCor(< /代码>)中的代码是一样的?

< P>明显的问题是C++代码使用了互不有效的C++类。VBA封送拆收器根本无法提供std::字符串。仅使用简单的POD类型进行互操作

在C++方面,对于字符串参数,接收指向空结束字符数组的指针,const char *。因为std::string有一个接受const char*的构造函数,所以根据您的需要调整这样的参数很简单


在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