带有C ++ DLL的Excel-VBA有时会崩溃 [英] Excel-VBA with C++ DLL sometimes crashes
问题描述
我只用了一个函数就制作了非常简单的c ++ dll:
I made really simple c++ dll with only one function:
int DLL_EXPORT __stdcall foo(double *source){return 0;}
我正试图像这样使用它:
and I'm trying to use it like that:
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死了).
and it usually works, but sometimes it crashes (Excel dies).
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 10的Excel 2016和Windows 8的Excel 2013上进行了测试 请告诉我哪里错了?您有没有在数组上正常使用C ++ DLL的示例吗?
I've tested on Excel 2016 on Windows 10 and Excel 2013 on Windows 8 Please tell me what is wrong? Do you have any example of non-crashing usage of C++ DLL working on arrays?
解决方法: 替换
Do Until FreeLibrary(library_address) = 0
Loop
使用
FreeLibrary library_address
我把它放在了循环中,因为有时FreeLibrary不起作用,但是我不在乎了.相关问题此处
I've put that in the loop because sometimes FreeLibrary doesn't work, but i don't care anymore. Related question here
推荐答案
VBA中的整数从-32768到32767.在C++
中,它更大,等效于VBA Long
.因此,尝试这样声明:
Integer in VBA is from -32768 to 32767. In C++
it is a way bigger, equivalent to the VBA Long
. Thus, try declaring like this:
Private Declare PtrSafe Function foo Lib "MyLibrary.dll" (ByRef arr As Double) As Long
让我展示我到目前为止所做的一切,这些工作对我有用(如果这是您想要的方式).无论如何,我已经做了一些更改,最好使用一些文本比较器来查看).
Let me show what I did so far, which worked for me (if this was the way you wanted it). Anyhow, I have changed a few things, it will be better to use some text comparer to see a bit).
- 我已经使用这篇文章来构建dll库(免责声明-是我自己的).
- cpp和def:
int __stdcall SimpleSlowMath(double *source)
{
return 0;
}
*.def看起来像这样:
The *.def looks like this:
LIBRARY "SomeLibrary"
EXPORTS
SimpleSlowMath
VBA:
The 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个样本.
As you see, the difference is that I declare the array with ()
here - ByRef arr() As Double
, but there are some other as well. Give it a try, for me it was working for 2000 samples.
这篇关于带有C ++ DLL的Excel-VBA有时会崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!