Ask Your Question
0

Passing arrays in Basic, works with Excel , error 73 in LibreOffice

asked 2020-01-13 22:37:09 +0100

gecos gravatar image

updated 2020-01-14 12:12:05 +0100

calling a (complex) method in external C dll (see below the header) the code works fine in Excel VBA (passing correctly all the arrays) while I get the error "BASIC runtime error. '73' Not implemented." from LibreOffice (in debugging phase, when calling mytest method), can you help with this error 73 ?
Should I adopt a different way to pass parameters ?

** C header (windows, test.dll) **

__declspec(dllexport) int WINAPI mytest(int,int,int,double*,double*,double*,double*,int,int,int,int*,int*,int,int*,int*,int*,double*,int,double*,int*,int*,int*,double*,double*);


** VBA in Excel 2016 **

Private Declare PtrSafe Function mytest Lib "test.dll" (ByVal csep As Long, ByVal stgnr As Long, ByVal init As Long, ByRef stgt As Double, ByRef stgp As Double, ByRef stgef As Double, ByRef stgdH As Double, ByVal prod_h As Long, ByVal btm_h As Long, ByVal fnr As Long, ByRef fstr As Long, ByRef fpos As Long, ByVal snr As Long, ByRef sstr As Long, ByRef spos As Long, ByRef sft As Long, ByRef sflow As Double, ByVal vnr As Long, ByRef vrv As Double, ByRef vtype As Long, ByRef stype As Long, ByRef siv As Long, ByRef srv As Double, ByRef flows As Double) As Long

Dim stgp(0 To 100) As Double  
Dim stgt(0 To 100) As Double
Dim stgef(0 To 100) As Double
Dim stgdH(0 To 100) As Double
Dim flows(0 To 2 * 100 * 100) As Double 
Dim sstr(0 To 2) As Long   
Dim spos(0 To 2) As Long
Dim sft(0 To 2) As Long
Dim sflow(0 To 2) As Double
Dim fstr(0 To 2) As Long    
Dim fpos(0 To 2) As Long
Dim vrv(0 To 1) As Double      
Dim vtype(0 To 1) As Long
Dim stype(0 To 1) As Long
Dim siv(0 To 1) As Long
Dim srv(0 To 1) As Double

    csep = 1 
    stgnr = 20
    init = 1 
    prod = 2 
    btm = 1 
    fnr =2
    snr = 2
    vnr = 2
    res = mytest(csep, stgnr, init, stgt(0), stgp(0), stgef(0), stgdH(0), prod, btm, fnr, fstr(0), fpos(0), snr, sstr(0), spos(0), sft(0), sflow(0), vnr, vrv(0), vtype(0), stype(0), siv(0), srv(0), flows(0))

** the same code converted to Libre Office **

(when executed, reports error : BASIC runtime error. '73' Not implemented.)

Private Declare Function mytest Lib "test.dll" (ByVal csep As Long, ByVal stgnr As Long, ByVal init As Long, stgt(), stgp(), stgef(), stgdH(), ByVal prod_h As Long, ByVal btm_h As Long, ByVal fnr As Long, fstr(), fpos(), ByVal snr As Long, sstr(), spos(), sft(), sflow(), ByVal vnr As Long, vrv(), vtype(), stype(), siv(), srv(), flows()) As Long

Dim stgp(0 To 100) As Double  
Dim stgt(0 To 100) As Double
Dim stgef(0 To 100) As Double
Dim stgdH(0 To 100) As Double
Dim flows(0 To 2 * 100 * 100) As Double 
Dim sstr(0 To 2) As Long   
Dim spos(0 To 2) As ...
(more)
edit retag flag offensive close merge delete

Comments

First of all, the preformatted text 101010 button is there for purpose. Without proper formatting, your code samples are unreadable.

Second: you need to debug step-by-step. Passing arrays to WINAPI functions from BASIC generally works. E.g., this using lstrlenW:

Private Declare Function lstrlenW Lib "kernel32" (str()) As Long

Sub test_lstrlenW
  Dim s(10) As Integer
  s(0) = 50
  s(1) = 20
  s(2) = 0
  Print lstrlenW(s())
End Sub

Are you building your DLL for the same architecture as LO (x86/x64)? Try first start with something simple, like 1-parameter function, to find the problem.

Mike Kaganski gravatar imageMike Kaganski ( 2020-01-14 08:03:46 +0100 )edit

3 Answers

Sort by » oldest newest most voted
0

answered 2020-01-14 13:20:46 +0100

Yes, passing more than 20 arguments to a library function is not implemented in LO: see call() definition.

edit flag offensive delete link more

Comments

thanks ! that answers my question, I must find out a way to reduce the numer of parameters (to 20)

gecos gravatar imagegecos ( 2020-01-14 13:41:24 +0100 )edit
0

answered 2020-01-14 10:21:03 +0100

gecos gravatar image

updated 2020-01-14 12:17:43 +0100

thanks for commenting my question, yes, LibreOffice Basic can work with arrays, the problem which i found is for that specific function where there are several arrays to pass (as pointers), my suspect is that there are limits in OpenOffice Basic interpreter so that it cannot pass many pointers or different pointers, maybe a LibreOffice developer can suggest the correct way to proceed in this case, probably I need to modify the code but I have no idea about the correct direction (i.e. reduce the number of parameters or redefine the pointers etc.),

according my tests OpenOffice/LibreOffice Basic interpreter works fine when passing arrays of doubles, see the folloing example (which works fine in my tests)

Public Declare Function mytest Lib "test.dll" (ByVal a As Long, ByVal b As Long, pt1(), pp1(), ph1(),ps1(), pv1(), ByVal c As Long) As Long

Dim pt(0 To 20) As Double
Dim pp(0 To 20) As Double
Dim ph(0 To 20) As Double
Dim ps(0 To 20) As Double
Dim pv(0 To 20) As Double

a =1
b =2
c = 20

nr = mytest(a, b, pt, pp, ph, ps, pv, c)

however even following the same rules when passing arrays as pointers, LibreOffice intepreter doesn't work with the example provided in my previous post, it would be useful to find some documents which explain how to pass a mix of different pointers (double, integers...)

edit flag offensive delete link more

Comments

(Concerning the content above:)
Passing an array "as pointer" should be equivalent to 'ByRef' in Basic and to the 'var' declaration in Pascal.
I won't comment on your specific function. It's too complicated for the purpose.
(Concerning this site:) Please
-1- use the 'add a comment' feature for commenting. The 'Add answer' feature should be used only if an answer to the question on top is intended. Each user (also the questioner) can only post one answer per question! Ongoing discussion must be poured into a sequence of comments.
-2a- use the tool 'preformatted text' for posting code. Otherwise it gets next to unreadable.
-2b- In case of code with very many lines: Decide consciously if it should better be made accessible via an attachment containing it.
-3- If possible at all, demonstrate your issue by an attached (reduced) LibO document showing it for you.
(-4- In your ...(more)

Lupp gravatar imageLupp ( 2020-01-14 11:45:39 +0100 )edit

...
Concerning the content again:
My answer was not about the question if Basic can work with arrays. It was about passing an array to a dll function. What can be done with one array should also be possible for many. If you experienced it otherwise, please refute my claim with a running erxample .ods. I would need the .dll compiled for Win10-64 bit (standard Intel processor).

Lupp gravatar imageLupp ( 2020-01-14 11:50:17 +0100 )edit

yes, I am converting some xls pages (tested with Excel 2016, 2019) to LibreOffice, there is a C dll compiled for Windows with CLang (32, 64) as well as Linux / Android, should you be interested I can provide the link to download

gecos gravatar imagegecos ( 2020-01-14 12:38:42 +0100 )edit

Tanks. Regarding the answer by @mie Kaganski I prefer to abstain from further investigation.

Lupp gravatar imageLupp ( 2020-01-14 13:37:46 +0100 )edit
0

answered 2020-01-14 00:17:10 +0100

Lupp gravatar image

updated 2020-01-14 00:19:43 +0100

Years ago I started a project needing to pass arrays to fast compiled routines available from a DLL.
I didn't continue that project, but a little preliminary study concerning the passing of arrays still exists. It worked (and still works). May be it helps a bit as is.
(I neither use MS Excel nor C.)
Code:

REM  *****  BASIC  *****
Option Explicit

Declare Sub doubleArray Lib _
"/AbsoluteFolderPathToTheDll/ArrayToDllVar.dll" _
Alias "doubleArray" (p1(), ByVal h0 As Long, ByVal h1 As Long)

Function arrayTimes2(pArray)
Dim rows As Long, columns As Long
rows = Ubound(pArray, 1) - Lbound(pArray, 1) + 1
columns = Ubound(pArray, 2) - Lbound(pArray, 2) + 1
doubleArray(pArray, rows, columns)
arrayTimes2 = pArray
End Function

'Follows the Pascal code I used to create the dll:

'library arrayToDllVar;
'{$mode objfpc}{$H+}
'
'uses
'  SysUtils, Classes;
'
'procedure doubleArray(var pA: Array of Double; h0, h1: Longint); cdecl;
'var y, x, ind : Longint;
'begin
'for y := 0 To h0-1 Do
'    begin
'    for x := 0 To h1-1 Do
'        begin
'        ind := y * h1 + x;
'        pA[ind] := pA[ind] * 2.0;
'        end;
'    end;
'end;
'
'exports
'doubleArray;
'end.

( I personall will not go back to the project the preliminary study was made for.)

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2020-01-13 22:37:09 +0100

Seen: 44 times

Last updated: Jan 14