带有C ++ DLL的Excel-VBA有时会崩溃 [英] Excel-VBA with C++ DLL sometimes crashes

查看:114
本文介绍了带有C ++ DLL的Excel-VBA有时会崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只用了一个函数就制作了非常简单的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).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆