Recent

Author Topic: Excel crashes after calling a Pascal DLL  (Read 381 times)

Idas

  • New member
  • *
  • Posts: 8
Excel crashes after calling a Pascal DLL
« on: October 30, 2020, 02:32:25 pm »
I have wrote a DLL in Free Pascal and want to call it in Excel with a VBA Macro but Excel crashes every time as soon as I run the Macro. I would be grateful if someone can help me out.

The Code of the DLL in Free Pascal is
Code: Pascal  [Select][+][-]
  1. library CLM_WEAdynModell;
  2. {$mode objfpc}{$H+}
  3.  
  4. uses
  5.     CLM_GlobalVariables, CLM_LoadCalc, CLM_Initialization;
  6.    
  7. type
  8.     IOA = array[1..150] of single;
  9.  
  10. procedure callTModel(var IOArray : IOA); stdcall;
  11. begin
  12.      getInputValues(IOArray);
  13.      defineModel;
  14.      calcSecForces;
  15.      writeOutputValues(IOArray);
  16.      writeLogFile(IOArray);
  17. end;
  18.  
  19. exports
  20.        callTModel;
  21. begin
  22. end.

And the Code of the VBA Macro is
Code: Text  [Select][+][-]
  1. Option Explicit
  2. Private Declare PtrSafe Sub callTModel Lib "D:\FS\LTMProjekt\TestWB\CLM_WEAdynModell.dll" (ByRef IOArray() As Single)
  3.  
  4. Private Sub CB_RUN_Click()
  5.  
  6. Dim ValID, TStep, INLimit, aIndex, bIndex, ActSensor, VisNmax, OUTLimit, i As Integer
  7. Dim TSim, TMax As Single
  8. Dim IOArray(149) As Single
  9.  
  10. With ActiveSheet
  11.  
  12. TStep = 0
  13. ValID = 0
  14. INLimit = 9  
  15. VisNmax = 20  
  16.  
  17. ActSensor = .Range("NoSensor").Value + 1
  18. OUTLimit = .Range("OUTLimit")
  19. TSim = 0
  20. TMax = .Range("TMax")
  21.  
  22.     ThisWorkbook.Worksheets("IstRes").Range("A4:IV8000").ClearContents
  23.  
  24. Application.ScreenUpdating = False
  25.  
  26.  Do While TSim < TMax
  27.     TSim = .Range("TSim")
  28.    
  29.     aIndex = (4 + TStep) 'Zeilenindex für Source Array
  30.     For i = 1 To INLimit
  31.      bIndex = (1 + i)     ' Spaltenindex für Source Array
  32.      
  33.      If (i < 10) Then IOArray(24 + i) = ThisWorkbook.Worksheets("SourceData").Cells(aIndex, bIndex).Value
  34.      bIndex = bIndex + INLimit
  35.      If (i < 10) Then IOArray(39 + i) = ThisWorkbook.Worksheets("SourceData").Cells(aIndex, bIndex).Value
  36.      bIndex = bIndex + INLimit
  37.      If (i < 4) Then IOArray(7 + i) = ThisWorkbook.Worksheets("SourceData").Cells(aIndex, bIndex).Value
  38.      bIndex = bIndex + 3
  39.      If (i < 4) Then IOArray(19 + i) = ThisWorkbook.Worksheets("SourceData").Cells(aIndex, bIndex).Value
  40.          
  41.     Next i
  42.    
  43.     IOArray(101) = OUTLimit
  44.    
  45.     Call callTModel(IOArray)
  46.    
  47.    
  48.     aIndex = (4 + TStep) 'Zeilenindex für Target Array
  49.     ThisWorkbook.Worksheets("IstRes").Cells(aIndex, 1).Value = ThisWorkbook.Worksheets("SourceData").Cells(aIndex, 1).Value
  50.     For i = 1 To OUTLimit
  51.      bIndex = (1 + i)     ' Spaltenindex für Source Array
  52.      ThisWorkbook.Worksheets("IstRes").Cells(aIndex, bIndex).Value = IOArray(101 + i)
  53.     Next i
  54.  
  55.     Application.ScreenUpdating = True
  56.      If TStep < VisNmax Then
  57.       .Cells(9 + TStep, 3).Value = ThisWorkbook.Worksheets("SollRes").Cells(aIndex, ActSensor).Value
  58.       .Cells(9 + TStep, 4).Value = ThisWorkbook.Worksheets("IstRes").Cells(aIndex, ActSensor).Value
  59.      Else
  60.       For i = 1 To (VisNmax - 1)
  61.        .Cells(8 + i, 3).Value = .Cells(9 + i, 3).Value
  62.        .Cells(8 + i, 4).Value = .Cells(9 + i, 4).Value
  63.       Next i
  64.       .Cells(8 + VisNmax, 3).Value = ThisWorkbook.Worksheets("SollRes").Cells(aIndex, ActSensor).Value
  65.       .Cells(8 + VisNmax, 4).Value = ThisWorkbook.Worksheets("IstRes").Cells(aIndex, ActSensor).Value
  66.      End If
  67.    
  68.     TStep = TStep + 1
  69.     .Range("TStep") = TStep
  70.    
  71.     Call ScrUpdateEnableNoFlicker
  72.    
  73.     Application.ScreenUpdating = False
  74.    
  75.  Loop ' Ende DoWhile TSim <= TMax
  76.  
  77.  
  78. End With ' ActiveSheet
  79. 'Application.ScreenUpdating = True
  80.  
  81.  
  82. End Sub
  83.  

I wrote another Test DLL where I passed a single by value from Excel to the Test DLL and that worked.
Code of what worked
Pascal DLL:
Code: Pascal  [Select][+][-]
  1. function test1(number : single):single;stdcall;
  2. begin
  3.      result := number;
  4. end
VBA Code:
Code: Text  [Select][+][-]
  1. Private Declare PtrSafe Function test1 Lib "D:\FS\LTMProjekt\TestWB\CLModul_lib.dll" (ByVal Number As Single) As Single
  2.  

So I think the problem is passing an array by reference from Excel to the Pascal DLL and I can't figure out where the problem is.
Maybe someone can help me out.

Thank you in advance!

bytebites

  • Sr. Member
  • ****
  • Posts: 364
Re: Excel crashes after calling a Pascal DLL
« Reply #1 on: October 30, 2020, 03:05:12 pm »
Just guess
Code: Pascal  [Select][+][-]
  1. procedure callTModel(var IOArray : IOA); cdecl

Idas

  • New member
  • *
  • Posts: 8
Re: Excel crashes after calling a Pascal DLL
« Reply #2 on: October 30, 2020, 03:34:42 pm »
Just guess
Code: Pascal  [Select][+][-]
  1. procedure callTModel(var IOArray : IOA); cdecl

I tried that but it still crashes. I think VBA has the calling convention stdcall.

Fred vS

  • Hero Member
  • *****
  • Posts: 2019
    • StrumPract is the musicians best friend
Re: Excel crashes after calling a Pascal DLL
« Reply #3 on: October 30, 2020, 03:42:06 pm »
Hello.

Maybe using cmem?

Code: Pascal  [Select][+][-]
  1. uses
  2.   cmem,  CLM_GlobalVariables, CLM_LoadCalc, CLM_Initialization;
  3.  

[EDIT]
And maybe using ctypes:

Code: Pascal  [Select][+][-]
  1. uses
  2.   cmem,  ctypes, CLM_GlobalVariables, CLM_LoadCalc, CLM_Initialization;
  3.  
  4. type
  5.     IOA = array[1..150] of cfloat;

« Last Edit: October 30, 2020, 03:57:54 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

jamie

  • Hero Member
  • *****
  • Posts: 4025
Re: Excel crashes after calling a Pascal DLL
« Reply #4 on: October 30, 2020, 03:43:27 pm »
U may also need to specify the call method in vb as well.
Otherwise like fp it will use its own call style and could vi register of its own format.
The only true wisdom is knowing you know nothing

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 9003
  • FPC developer.
Re: Excel crashes after calling a Pascal DLL
« Reply #5 on: October 30, 2020, 04:29:13 pm »
Yes.  Can VBA really work with static arrays ? Isn't it a safearray under the hood? Maybe safearray wrapped in a variant even.

Idas

  • New member
  • *
  • Posts: 8
Re: Excel crashes after calling a Pascal DLL
« Reply #6 on: October 30, 2020, 04:47:11 pm »
Thank you all!

I found an answer. The way which is working for me is:

You call the DLL with a single scalar, the first element of the array by reference:
Code: Text  [Select][+][-]
  1. Private Declare PtrSafe Sub callTModel Lib "D:\FS\LTMProjekt\TestWB\CLM_WEAdynModell.dll" (ByRef IOArray As Single)
  2.  

and

Code: Text  [Select][+][-]
  1. Call callTModel(IOArray(0))
  2.  

 

TinyPortal © 2005-2018