使用C ++ DLL的Excel-VBA有时会崩溃

我只用一个函数做了一个非常简单的c ++ dll:

int DLL_EXPORT __stdcall foo(double *source){return 0;} 

我正在尝试使用它:

 Option Explicit Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPtr Private Declare PtrSafe Function FreeLibrary Lib "kernel32" (ByVal hLibModule As LongPtr) As Long Private Declare PtrSafe Function foo Lib "MyLibrary.dll" (ByRef arr As Double) As Long Sub test_foo(n As Long) Dim i As Long Dim library_address As LongPtr Dim library_path As String library_path = "global_path\MyLibrary.dll" library_address = LoadLibrary(library_path) Dim arr() As Double ReDim arr(1 To n) As Double For i = 1 To n arr(i) = CDbl(Cells(i, 1).Value) Next foo arr(1) Do Until FreeLibrary(library_address) = 0 Loop End Sub 

它通常工作,但有时它崩溃(Excel死亡)。

 Faulting application name: EXCEL.EXE, version: 16.0.8625.2139, time stamp: 0x5a162a41 Faulting module name: MyLibrary.dll_unloaded, version: 0.0.0.0, time stamp: 0x000000e2 Exception code: 0xc0000005 Fault offset: 0x00001230 Faulting process id: 0x1828 

我已经在Windows 8上testing了Windows 10和Excel 2013上的Excel 2016请告诉我什么是错误的? 你有没有崩溃的使用C + + DLL在数组上工作的例子?

解决方法:replace

 Do Until FreeLibrary(library_address) = 0 Loop 

 FreeLibrary library_address 

我已经把它放在循环中,因为有时FreeLibrary不起作用,但我不在乎。 相关问题在这里

VBA中的整数是从-32768到32767.在C++它是一个更大的方法,相当于VBA Long 。 因此,尝试像这样声明:

Private Declare PtrSafe Function foo Lib "MyLibrary.dll" (ByRef arr As Double) As Long


让我来说明我到目前为止做了什么,这对我有用(如果这是你想要的方式)。 无论如何,我已经改变了一些东西,最好是使用一些文本比较器来看看)。

  • 我用这篇文章来build立DLL库(免责声明 – 这是我自己的) 。
  • cpp和def:

 int __stdcall SimpleSlowMath(double *source) { return 0; } 

* .def看起来像这样:

 LIBRARY "VitoshAcademy" EXPORTS SimpleSlowMath 

VBA:

 Option Explicit Public Const myPathDll = "C:\Users\your-own-path\Debug\vityata051217.dll" Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" _ (ByVal lpLibFileName As String) As Long Private Declare PtrSafe Function FreeLibrary Lib "kernel32" _ (ByVal hLibModule As LongPtr) As Long Private Declare PtrSafe Function SimpleSlowMath Lib "vityata051217.dll" _ (ByRef arr() As Double) As Long Sub Try(n As Long) Dim i As Long Dim library_address As Long Dim library_path As String library_path = myPathDll library_address = LoadLibrary(library_path) Dim arr() As Double ReDim arr(1 To n) As Double For i = 1 To n arr(i) = CDbl(Cells(i, 1).Value) Next Debug.Print SimpleSlowMath(arr) End Sub Public Sub TestMe() Dim n As Long For n = 1 To 50 Try n Debug.Print n Next n End Sub 

正如你所看到的,区别在于我用()在这里声明了数组 – ByRef arr() As Double ,但也有其他一些。 试一试,对我来说,这是2000年的样品。