Calling external functions

Just starting out? Need help? Post your questions and find answers here.
Capella
User
User
Posts: 16
Joined: Wed Mar 19, 2008 5:32 pm

Calling external functions

Post by Capella »

Hi!

I have DLL (compiled in C for Windows) with functions that I want to use.
Many of the functions have parameters as Double and also returns Double. Some functions also returns Arrays of Doubles.

As I understand it, I have to use "Prototype" to access these function, since the normal way of handling DLL's cannot handle Float or Double.

My question now, is PureBasic able to handle this?

If so, any sample code is apprecited based on the following Visual Basic declaration of one such function:

Declare Function calculate Lib "calc32.dll" _
Alias "_calc@24" ( _
ByVal tjd As Double, _
ByVal ipl As Long, _
ByVal iflag As Long, _
ByRef x As Double, _
ByVal serr As String _
) As Long

Note: The variable x above of the parameters is returning an array of 6 different numbers as doubles, similar to x(6) as Double in VB.
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Re: Calling external functions

Post by tinman »

Capella wrote:My question now, is PureBasic able to handle this?
Yes. Or at least, it should be. You might also be able to import the functions directly rather than having to use prototypes, I'm not sure if imported functions have the same limitations as CallFunctionFast() etc.

I'm not sure about the string parameter.

Code: Select all

Import "calc32.lib"
    calculate.l(tjd.d, ipl.d, iflag.l, *x.d, serr.s) As calc
EndImport

Dim real_x.d(6)
calculate(1, 2, 3, @real_x(0), "foo")
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

PB can't handle returning array of double. I didn't even know you could do that in C.
walker
Enthusiast
Enthusiast
Posts: 634
Joined: Wed May 05, 2004 4:04 pm
Location: Germany

Post by walker »

isn't

Code: Select all

 ByRef x As Double, _ 
simply a pointer to that array?
Capella
User
User
Posts: 16
Joined: Wed Mar 19, 2008 5:32 pm

Functions returning array of double

Post by Capella »

It can be done in C and it can be done Visual Basic, so I don't understand why PureBasic cannot handle this - returning an array of doubles from an external function call.

I had the impression that PB would be a more sophisticated language than VB, but apparently not. Or?

Is this a problem with external functions only, or is this a problem with "normal" functions calls as well? I have the C so source code, so I could re-compile the function to use additional parameters instead of an array. But I prefer not, as I then also have to make other changes as well.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Actually, that VB code does not return an array of doubles. It returns a long. PB can handle that VB function just fine.
Capella
User
User
Posts: 16
Joined: Wed Mar 19, 2008 5:32 pm

Returning arrays of long

Post by Capella »

Yes, the return value is a long, which in this case is a value to control if the calculations within the functions was done correctly or not.

However, I must also be able to read some of the parameters (here delcared as Global), which have been calculated within the function, and especially the array (the 4th parameter containing the array of calculated data, and the 5th parameter which contains any error message).

In PB I have written it like this (a short sample)...

Note: I've manage to create a static "lib" out from the "dll", so I first import that, then use prototypes in order to be able to use doubles, and pointers to the functions to simplify the coding thereafter...

;-------------------------------------------------------------
Import "calc32.lib"
calc32 (a.d, b.l, c.l, d.d, e.s) As "_calc@32"
EndImport
Prototype.l FunctionC (a.d, b.l, c.l, d.d, e.s, f.l=1)
*PointerC.FunctionC=@calc32()

jd.d = 2436858.58333
no.l = 0
flg.l = 512
Global Dim pos.d(6)
Global erro.s = ""

ret.l = *PointerC (jd.d, no.l, flg.l, @pos.d, erro.s);

OpenConsole()
PrintN (StrD (pos.d(1))
CloseConsole()
;----------------------------------------------------
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

There are some errors in your code.

- If you use import you don't need the prototypes.
- "ByRef x As Double" is a POINTER to a double, you declared it as a double.
- You used "As "_calc@32"", but the original definition uses @24. PB can even figure out this by itself, so you don't need it.
- You send @pos.d, which is the address of the double variable "pos". That is a completely different variable than the array pos().
- Pos(6) has 7 elements, from 0 to 6. You only need 6.
- You print Pos(1) as the first element, but the first element is Pos(0)
Post Reply