PDA

View Full Version : arrays not "equal..." or yes...



Oscar Ugolini
29-09-2012, 10:42
I try to pass an array "pointer" to an external function,
but i see some different things...
The dynamic array is stored in a string, and restored from it...

i try 2 methods :

1) method (THIS METHOD WORK OK...but it's a little bit slow...)

dim pointer as string 'this could be in my UDT for example

dim pts(10) as single
dim ptscopy(10) as single

pts(1)=1: pts(2)=2 ....
pointer=peek$( varptr( pts(1) ),sizeof( pts() ) ) 'store array at string address
....
'-------------restore array data from string -----------------------------------------
poke$( varptr( ptscopy(1) ), pointer ) 'store pointer string in ptscopy array
....
ext_function(ptscopy)

This first method work fine, but if i have more and more objects to "peek and poke" every tyme,
will too slow for me :(

2) method (THIS SEEMS WORK for thinbasic, but not for my ext_function :()

dim pointer as string 'this could be in my UDT for example

dim pts(10) as single
'''''''dim ptscopy(10) as single 'i do it later

pts(1)=1: pts(2)=2 ....
pointer=peek$( varptr( pts(1) ),sizeof( pts() ) ) 'store array at string address
' i can keep this "peek", because i use it only one time when load data ---------
....
'-------------restore array data from string -----------------------------------------
dim ptscopy(10) as single AT strptr(pointer)
....
ext_function(ptscopy)

If i check elements in ptscopy are ok, but when i pass it this array doesn't work...
I have tried also with MULTIDIMENSIONAL Array ... work only FIRST METHOD...

Can anyone help me? thanks... :)
Bye,
Oscar

ErosOlmi
29-09-2012, 15:04
Can you please show how is your ext_function Function defined ?
Most of the understanding how to pass data depends on this


I don't see the reason you need to make a copy of your array before passing it to external function unless your external function tryes to change value of the array and you do not want.
Anyway we will leave this for later discussions.


Passing arrays or in general big amount of data to functions (internal or external) is usually performed into 2 way: BYREF or by pointer to first byte.
BYREF is normally used when function is inside your application mainly because you application knows what you are passing (what data type, how many elements in the structure you are passing, ...)

Assuming your external function is something like:

DECLARE FUNCTION ext_function LIB "LibName" ALIAS "ext_function" (BYVAL PtrToArrayOfSingle AS DWORD) AS ...
(that is: your function expects a pointer to the first element of the array)
your thinBasic code should be something like:

ext_function(VARPTR(pts))

But I suspect your external function also would like to know how many elements the array has so it should be something like:

DECLARE FUNCTION ext_function LIB "LibName" ALIAS "ext_function" (BYVAL PtrToArrayOfSingle AS DWORD, BYVAL nElements AS DWORD) AS ...
and called like this

ext_function(VARPTR(pts), UBOUND(pts))

Oscar Ugolini
01-10-2012, 07:13
Ciao Eros,
I missed to insert in the code the DECLARE FUNCTION :) sorry...

In this case i'm working with thinbasic_glu.inc module, and i use this function was declared as :


Declare Sub gluNurbsCurve Lib "glu32.dll" Alias "gluNurbsCurve" (ByVal nobj As DWord, ByVal nknots As GLint, ByRef knot As GLfloat, ByVal stride As GLInt, ByRef ctlarray() As GLfloat, ByVal order As GLint, ByVal ntype As GLEnum)


2 arrays are declared "byref" parameter, knot and ctlarray()...

referred to my first post, with method n.1 TB and "gluNurbsCurve" work fine, with method n.2 TB seems work ok, but not "gluNurbsCurve"... I've checked array elements and seems ok... :(

thanks :)
ciao dalla Romagna ... "bye from Romagna"
Oscar

ErosOlmi
01-10-2012, 07:32
Oscar,

is it possible for you to produce a minimal example I can work on to better understand the situation and make simulations?

Also: what thinBasic version are you using?

Thanks a lot
Eros

Oscar Ugolini
01-10-2012, 20:26
Hi Eros,
i made a simple example of a real nurbs curve render with glu include...

There are 2 sub drawarray1 (work ok but a bit slow with more and complex nurbs) and drawarray2 (this is a try to work without "peeking" all time data from string (pointer array), but passing directly if it's possible the array memory block to ext funct gluNurbsCurve...

Have you some tricks to give this result??

Thanks, bye
Oscar

ErosOlmi
01-10-2012, 21:10
Great Oscar,

thanks a lot for this example, it is exactly what I needed in order to test where can be the problem.
I will check and let you know.

Ciao
Eros

ErosOlmi
01-10-2012, 21:44
OK, now I see.

OK, one way to solve the problem is the following.

If you function expects a BYREF data (in this case an array), you can tell thinBasic you already have calculated the pointer to your data using BYVAL in this way:

gluNurbsCurve(theNurb, 11, BYVAL StrPtr(Knots), _
4, pts, _
4, %GL_MAP1_VERTEX_4)

Because gluNurbsCurve expect an array (BYREF MyArray() As WathEvere) it will parse for an array.
But if you want to pass a pointer to a memory area where YOU know is stored the array, you can force it using BYVAL clause.
thinBasic will trust that value as the pointer to the memory data.

Finally after BYVAL you need to pass the pointer to the data.
To get the pointer to data using a dynamic string you need to use STRPTR and not VARPTR

thinBasic dynamic string are OLE strings (or BSTR in other languages) that is they a represented in memory by a pointer that points to a dynamic memory area handled by OLE APIs.
When you use VARPTR to a dynamic string what you get is a pointer to to pointer
When you use STRPTR to a dynamic string what you get is a pointer to the string pointed by the OLE string.

More info on OLE (or BSTR) string: http://www.thrysoee.dk/InsideCOM+/ch05b.htm or http://www.orin.jp/e/dev/tutorial_rao.html


You can also use your original array:

gluNurbsCurve(theNurb, 11, ByVal VarPtr(memknts(1)), _
4, pts, _
4, %GL_MAP1_VERTEX_4)




Let me know if this fix the problem.

Ciao
Eros

Oscar Ugolini
01-10-2012, 21:57
---->>>> BYVAL StrPtr(Knots)
this is the solution i'm looking for!!! :yahoo:
...
i'm working on my cad/cam (with IGES format import) TB project...
i will post as soon as a demo... thanks boss! :)

bye,
Oscar

ErosOlmi
01-10-2012, 22:16
One question: I'm not an expert in this 2D/3D field so it can be a stupid question but why are you duplicating your data before passing to gluNurbsCurve function?

Oscar Ugolini
01-10-2012, 22:51
yeah Eros,
i wrote this simple code to ask you a method to pass those datas to the function, without peek and poke continuosly...
exactly, i use and UDT for the object, and inside it, i must store all the data and dynamic arrays i need when i load the file (i use dynamic string like Petr have suggest to me :)).
And when i render all the scene, i must "extract" these arrays and pass them to gluNurbsCurve or gluNurbsSurface. So i can have an object variable, with all datas referring to it.
And work very well now with your help, more efficient like before...

thanks to You and Petr of course...
bye,
Oscar

ErosOlmi
01-10-2012, 23:00
Ok, now I see it.

Anyway, thanks to you too!
Thanks to your asking, I think I've discovered a problem in thinBasic Core engine when passing absolute arrays (the one created with DIM ... AT ...) BYREF
I'm still testing it but I'm pretty sure I will have a bug more fixed in next version :D

Ciao
Eros