我在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这个例子运行正常。
答案 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时,它是有效的。