Newbie DLL Help

BlitzMax Forums/BlitzMax Programming/Newbie DLL Help

wmaass(Posted 2011) [#1]
Hoping for a little help here, that is if any one can make sense of my mess below.

I created a module so that could use a certain dll to access some data from a vision system. Most of it works shockingly well given my inexperience with creating modules and using dlls. I feel like I totally lucked out there. However I can’t figure out one issue:

There is a function in the dll that is something like so:

mydll_API int mydll_shot(double *l_angle, double *s_angle, double *vel,
				double *s_rps, double *s_axis, char* s_path, int* s_index,
				float* s_confidence, float* t_confidence, int* cam_count );



My module is set up like:

Import "-lpdsdll" 

Extern
     Function mydll_shot:Int(l_angle:Double Ptr, s_angle:Double Ptr, vel:Double Ptr, s_rps:Double Ptr, s_axis:Double Ptr, s_path:Byte Ptr, s_index:Int Ptr, s_confidence:Float Ptr, t_confidence:Float Ptr, cam_count:Int Ptr )
End Extern




Then in my BMax app I setup and use the function like this:


'create some variables

Local sLaunch:Double
Local sSlice:Double
Local sVel:Double
Local sSpin:Double
Local sSpinAxis:Double
Local sShotPath:Byte
Local sIndex:Int
Local sSpinConf:Float
Local sTrajConf:Float
Local sCamCount:Int


Local Launch:Double Ptr = Varptr sLaunch
Local Slice:Double Ptr = Varptr sSlice
Local Vel:Double Ptr = Varptr sVel
Local Spin:Double Ptr = Varptr sSpin
Local SpinAxis:Double Ptr = Varptr sSpinAxis
Local ShotPath:Byte Ptr = Varptr sShotPath
Local Index:Int Ptr = Varptr sIndex
Local SpinConf:Float Ptr = Varptr sSpinConf
Local TrajConf:Float Ptr = Varptr sTrajConf
Local CamCount:Int Ptr = Varptr sCamCount



'in my main loop somewhere

Local sTest:Int = mydll_shot(Launch, Slice, Vel, Spin, SpinAxis, ShotPath, Index, SpinConf, TrajConf, CamCount)

Local tLaunch:Double = Launch[0] ' this is vlaunch, good
Local tSlice:Double = Slice[0] ' h angle, good
Local tVel:Double = Vel[0] ' 2nd spin component for some reason, bad
Local tSpinAxis:Double = SpinAxis[0] ' 1st spin component, good
Local tShotPath:Byte = ShotPath[0]' shot path, good
Local tIndex:Int = Index[0] ' shot index, good
Local tSpinConf:Float = SpinConf[0] 'spin confidence, good
Local tTrajConf:Float = TrajConf[0] ' trajectory confidence, good
Local tCamCount:Int = CamCount[0] ' num cams used to detect ,good
			
			


Which produces correct data for all but 2 of the items above.

For example tLaunch is good, tSlice is good but tVel is not.

In fact tVel looks like it gives me data that seems to belong to tSpinAxis. tSpinAxis is also among the "good data" list.

If I print tSpinAxis[0],tSpinAxis[1] etc I get the x,y,z spin axis components.

If I print tVel I appear to get the same value found in tSpinAxis[1] instead of a speed in mps.

Not getting tVel is killing me and I must not be doing this right at all. Any ideas?

Last edited 2011


Brucey(Posted 2011) [#2]
What is tLaunch for, if you already have the value in sLaunch?


wmaass(Posted 2011) [#3]
That's just crappy code. Below is better, same odd result:


Local sTest:Int = pdsdll_shot(Launch, Slice, Vel, Spin, SpinAxis, ShotPath, Index, SpinConf, TrajConf, CamCount)


Print "Launch Angle: " + Launch[0]
Print "Horizontal Angle: " + Slice[0]
Print "Velocity: " + Vel[0]
			
			
For Local i:Int = 0 To SizeOf(SpinAxis)-1
	Print "SpinAxis " + i + ": " + SpinAxis[i]
Next



Which give me the output:

Launch Angle: 22.415546595975869
Horizontal Angle: 0.84882662730908176
Velocity: 0.97845867560724509
SpinAxis 0: 0.12183189775602525
SpinAxis 1: -0.16666015966055403
SpinAxis 2: 0.97845867560724509
SpinAxis 3: 0.84882662730908176

See how Velocity is the same as SpinAxis 2. Also, why is the size of SpinAxis 4? I would expect it to be 3 (x,y,z).

Here are the correct values I am looking for (output from the app that interfaces with the cameras).

Rifle 232, Back 6379, Left -1173, Total 6508
Total spin ( 0.122, -0.978, -0.167) 108.46
LAUNCH ANGLE 22.42 DEGS LEFT ANGLE 0.85 DEGS
VELOCITY 45.54 mps 101.9 MPH


Last edited 2011

Last edited 2011

Last edited 2011


skidracer(Posted 2011) [#4]
Not sure if it will help but Extern should probably be Extern "C" in your code.


wmaass(Posted 2011) [#5]
Thanks for the tip skidracer. I've gotten around the issue buy wrapping another function that is in the dll that gives me the velocity proper. Still would like to understand this stuff someday.

Oh, thanks for shedding light on that redundant stuff Brucey, everything is much cleaner now.

Last edited 2011


col(Posted 2011) [#6]
Hiya,


Also, why is the size of SpinAxis 4? I would expect it to be 3 (x,y,z)



SpinAxis is size of 4 because SpinAxis is a pointer, which means its a 32bit memory address, having 8bits per byte giving a value of 4 bytes. When you de-reference the pointer using the SpinAxis[0], BMax will look at the address stored in SpinAxis, then read back 8 bytes ( 8 bytes are used to store a Double, 4 for Float etc ) from that address.

A little example :-

Local sLaunch:Double '8 bytes are used to store this value
Local sSlice:Double '8 bytes are used to store this too

Local Launch:Double Ptr = Varptr sLaunch '4 bytes for this value ( memory address pointer )
Local Slice:Double Ptr = Varptr sSlice '4 bytes again for this

Say Slice has a value of $00ADFF0C ( 32bits address value, 4 bytes ), then this is the address of sSlice, ie the value of sSlice is stored at $00ADFF0C
And say Launch has a value of $00ADFF14 so this is the address of sLaunch.

Notice that Launch is 8 bytes higher than Slice, because 8 bytes are for the Double.

If you use Slice[0] = 10.0, then as sSlice is stored at $00ADFF0C, the sSlice variable will now become 10.0
If you use Slice[1] = 20.0, then you are actually referrencing the address $00ADFF14 ( 8 bytes above $00ADFF0C because Slice is a Double pointer)
which is also the address of sLaunch, so you would actually be altering the value of the sLauch variable.

The same applies when reading back the values using Slice[0],Slice[1] etc...
You need to be careful when playing with pointers making sure that you are pointing and reading to/from the correct addresses.

It really helps to see in it action, so here is a screeny, note the values on the right hand side in the variables window.
It really is a hit or miss affair whether the above scenario actually occurs, it just depends on what memory address the variables get assigned to upon program execution. Using an extract from from code above, I get this :-



Last edited 2011


col(Posted 2011) [#7]
Douple post???

Last edited 2011


wmaass(Posted 2011) [#8]
Great info col, this helps a lot. Thanks for taking the time to put that together.


wmaass(Posted 2011) [#9]
I am looking at the .h file for the dll and I notice this:

double* someVar

or...

double *someVar

Is there a difference between the 2 based on where the "*" is placed?


Brucey(Posted 2011) [#10]
Nope


wmaass(Posted 2011) [#11]
Thanks Brucey. One more on this dll:

I am trying to wrap this:

mydll_getstatus( int& CurrShotIndex, char* StatusMsg );

The way I understand this is that the "&" indicates a reference. How do you deal with that when wrapping this function?


Brucey(Posted 2011) [#12]
It's a pointer to your integer.

You can probably define it like this :


Function mydll_getstatus(CurrShotIndex:Int Ptr, StatusMsg:Byte Ptr)




col(Posted 2011) [#13]
Hiya,

You're welcome :-)
I'm glad you found it useful.


wmaass(Posted 2011) [#14]
Yep, that works Brucey. Thanks guys.