【发布时间】:2016-01-15 03:39:34
【问题描述】:
我尝试将一个双精度数组从 VB 传递到 C++(希望最终反过来)。
我查看了几个页面,这些页面似乎表明一个方法看起来有点像以下(但在 mydll.cpp 中传递给 myfun 的参数更多): 在 C++ 中 (mydll.cpp)
extern __declspec(dllexport) int __stdcall myfun(LPSAFEARRAY FAR arrayCppIn)
{
double *pArray;
pArray = (double*)((*arrayCppIn)->pvData);
double testvar = pArray[0]
}
这个连同VB代码(vbtestcppdll):
Public Declare Function myfun Lib "mydll.dll" (ByRef arrVBout() As Double) As Integer
Dim result As Integer
Dim testarr = New Double {1.1, 2.5, 6}
result = myfun(testarr)
在调试模式 (MSVS2013) 下,当我到达double testvar = pArray[0] 时,我得到“vbtestcppdll.exe 中出现“System.AxxessViolationException”类型的未处理异常”
再往下说,“这通常表明内存已损坏”。 PLSAFEARRAY 的 cDims、cbElements、cElements 似乎都已损坏。
标量(整数和双精度)都按应有的方式通过。
有人有什么想法吗??
(我得到了帮助: http://www.flipcode.com/archives/Interfacing_Visual_Basic_And_C.shtml)
【问题讨论】:
-
pArray = (double*)((arrayCppIn)->pvData);你真的想要对 arrayCppIn 的双重间接还是应该是 pArray = (double)((arrayCppIn).pvData);或 pArray = (double)(arrayCppIn->pvData);我面前没有任何类型文档,但这是一个猜测。您也许可以在这一行使用调试器来准确确定您希望看到的内容。
-
不应该是
pArray = (double*)(arrayCppIn->pvData);。您的示例甚至不应该是可编译的。 -
不行,它需要所有的*,否则无法编译。 AFAIU LPSAFEARRAY 是指向 SAFEARRAY 的指针
-
<MarshalAs(UnmanagedType.SafeArray)>是必需的,因此 pinvoke 编组器知道它需要创建一个安全数组,而不仅仅是传递指向第一个数组元素的指针。 -
感谢@Hans Passant,解决了它!