使用字符串和VBA与C ++之间的另一个UDT崩溃UDT

时间:2015-12-30 17:07:01

标签: c++ excel vba

我在VBA和C ++之间有问题。 当我想要重新编写我的X阵列时,它会因我的发行版dll而崩溃。 如果我在debug中编译,它有时会工作但是当我查看我的X数组时,我有一个错误“应用程序定义或对象定义的错误”。

如果我不重新编写X数组或者删除了s字符串,那么它可以正常工作。

VBA:

Private Declare PtrSafe Function Cpp_D2 Lib "MyDLL.dll" (i As T) As Long

Private Type XData
    X() As Double
    Count As Long
End Type

Private Type T
    s As String
    data_T As XData
End Type

Sub Test()
    Dim i As T
    ReDim i.data_T.X(5)
    i.s = "ok"
    Call Cpp_D2(i)
End Sub

C ++:

__declspec(align(4)) typedef struct XData
{
    LPSAFEARRAY X;
    int Count;
}   XData;

__declspec(align(4)) typedef struct T
{
    BSTR s;
    XData X;
} T;

__declspec(dllexport) int __stdcall  Cpp_D2(T *p)
{
    double *x = NULL;
    HRESULT hr = SafeArrayAccessData(p->X.X, reinterpret_cast<void**>(&x));
    SafeArrayUnaccessData(p->X.X);
    return 0;
}

我使用32位版本的Excel和Visual Studio 2010来编译c ++ dll。

在Mac上,我在崩溃前有一条消息:“内部错误(错误51)”有关此错误的官方文档的信息是:

“Visual Basic中发生内部故障。除非此调用是由Error语句或Raise方法生成的,否则请与Microsoft产品支持服务联系以报告消息出现的条件。”

我使用这个例子来完成这项工作:https://support.microsoft.com/en-us/kb/171583这个例子运行正常。

1 个答案:

答案 0 :(得分:0)

我不知道为什么内存已损坏,但我找到了解决方法。 我们不需要在C ++中改变任何东西。在VBA上,目标是传递用户定义类型ByVal的地址,如下所示:

Call Cpp_D2(VarPtr(i))

并且,更改C ++函数的声明非常重要:

Private Declare PtrSafe Function Cpp_D2 Lib "MyDLL.dll" (ByVal i As Long) As Long

现在,当我在C ++中使用声明和没有MIDL的用户定义类型的VBA时,它是有效的。