Passing of variable to DLL not taking place

Just starting out? Need help? Post your questions and find answers here.
Blurryan
User
User
Posts: 32
Joined: Sat Oct 13, 2007 2:08 pm
Location: Kazakhstan

Passing of variable to DLL not taking place

Post by Blurryan »

Below is the DLL file, compiled as "Astro2_0.dll: and the second file is the calling program. The third file is a normal function call inside a normal program.

The function computes the Julian Day. The function takes 3 variables, day as double, and month and year as integers. In calling the DLL, the day is not being passed, but in the normal function call the program is smooth.

Results of both are given below the code.

Can someone point out where I am going wrong? I would prefer not to use a Prototype.

Astro2_0.dll code

Code: Select all

Global JulD.d

ProcedureDLL.d JulianDay(d1.d, m.i, y.i)
    Protected a.i, b.i, dd.d, mm.i, yy.i
    dd = d1: mm = m: yy = y
    If yy > 1582: GJ = "G": EndIf
    If yy < 1582: GJ = "J": EndIf
    If yy = 1582
        If mm > 10: GJ = "G": EndIf
        If mm < 10: GJ = "J": EndIf
        If mm = 10
            If dd > 14: GJ = "G": EndIf
            If dd < 5 : GJ = "J": EndIf
        EndIf
    EndIf
    If mm > 2: mm = mm + 0: yy = yy + 0: ElseIf mm = 1 Or mm = 2: yy = yy - 1: mm = mm + 12: EndIf
    a = Int(yy / 100)
    If GJ = "J": b = 0: Else: b = 2 - a + Int(a / 4): EndIf
    JulD = Int(365.25 * (yy + 4716)) + Int(30.6001 * (mm + 1)) + dd + b - 1524.5
    ProcedureReturn @JulD
EndProcedure
DLL Calling program - with results of the call. Notice May 15th and 31st and June 15th and 30th are same figures, so effectively ignoring day value.

Code: Select all

If OpenLibrary(0, "Astro2_0.dll")
   Debug "01/01/0001 - " + StrD(PeekD(CallFunction(0, "JulianDay", 1.0, 1, 1)), 1)      ;1721423.5 - 1721422.5
   Debug "30/04/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", 30.0, 4, 2016)), 1)  ;2457508.5 - 2457478.5
   Debug "15/05/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", 15.0, 5, 2016)), 1)  ;2457523.5 - 2457508.5
   Debug "31/05/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", 31.0, 5, 2016)), 1)  ;2457539.5 - 2457508.5
   Debug "15/06/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", 15.0, 6, 2016)), 1)  ;2457554.5 - 2457539.5
   Debug "30/06/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", 30.0, 6, 2016)), 1)  ;2457569.5 - 2457539.5
Else
    MessageRequester("ERROR", "Can't open Library Astro2_0", #PB_MessageRequester_Ok)
EndIf
CloseLibrary(0)

; Results of the above Call are:
; 
; 01/01/0001 - 1721422.5
; 30/04/2016 - 2457478.5
; 15/05/2016 - 2457508.5
; 31/05/2016 - 2457508.5
; 15/06/2016 - 2457539.5
; 30/06/2016 - 2457539.5
Normal program with internal function - results are below the code.

Code: Select all

Procedure.d JulianDay(d.d, m.i, y.i)
    Protected a.i, b.i
    If y > 1582: GJ.s = "G": EndIf
    If y < 1582: GJ = "J": EndIf
    If y = 1582
        If m > 10: GJ = "G": EndIf
        If m < 10: GJ = "J": EndIf
        If m = 10
            If d > 14: GJ = "G": EndIf
            If d < 5 : GJ = "J": EndIf
        EndIf
    EndIf
    If m > 2: m = m + 0: y = y + 0: ElseIf m = 1 Or m = 2: y = y - 1: m = m + 12: EndIf
    a = Int(y / 100)
    If GJ = "J": b = 0: Else: b = 2 - a + Int(a / 4): EndIf
    dd = d+h/24+i/24/60+s/24/3600
    JulD.d = Int(365.25 * (y + 4716)) + Int(30.6001 * (m + 1)) + Int(d) + b - 1524.5
    ProcedureReturn JulD
EndProcedure

a1.d = JulianDay(1.0, 1, 1)
b1.d = JulianDay(30.0, 4, 2016)
c1.d = JulianDay(15.0, 5, 2016)
d1.d = JulianDay(31.0, 5, 2016)
e1.d = JulianDay(15.0, 6, 2016)
f1.d = JulianDay(30.0, 6, 2016)

Debug "01/01/0001 - " + StrD(a1, 1)
Debug "30/04/2016 - " + StrD(b1, 1) + " - " + StrD(b1-a1, 0)
Debug "15/05/2016 - " + StrD(c1, 1) + " - " + StrD(c1-b1, 0)
Debug "31/05/2016 - " + StrD(d1, 1) + " - " + StrD(d1-c1, 0)
Debug "15/06/2016 - " + StrD(e1, 1) + " - " + StrD(e1-d1, 0)
Debug "30/06/2016 - " + StrD(f1, 1) + " - " + StrD(f1-e1, 0)

; Results of the above Call are:
; 
; 01/01/0001 - 1721423.5
; 30/04/2016 - 2457508.5 - 736085
; 15/05/2016 - 2457523.5 - 15
; 31/05/2016 - 2457539.5 - 16
; 15/06/2016 - 2457554.5 - 15
; 30/06/2016 - 2457569.5 - 15
Blurryan
User
User
Posts: 32
Joined: Sat Oct 13, 2007 2:08 pm
Location: Kazakhstan

Re: Passing of variable to DLL not taking place (Solved) but

Post by Blurryan »

Ok. I think I understood. I need to pass a pointer to the DLL from the calling program.

Can someone vet if this is correct or is there something more to it?

Calling program for DLL as changed

Code: Select all

If OpenLibrary(0, "Astro2_0.dll")
    x.d = 1: y.d = 15: z.d = 30: zz.d = 31
   Debug "01/01/0001 - " + StrD(PeekD(CallFunction(0, "JulianDay", @x, 1, 1)), 1)      ;1721423.5 - 1721422.5
   Debug "30/04/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", @z, 4, 2016)), 1)  ;2457508.5 - 2457478.5
   Debug "15/05/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", @y, 5, 2016)), 1)  ;2457523.5 - 2457508.5
   Debug "31/05/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", @zz, 5, 2016)), 1)  ;2457539.5 - 2457508.5
   Debug "15/06/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", @y, 6, 2016)), 1)  ;2457554.5 - 2457539.5
   Debug "30/06/2016 - " + StrD(PeekD(CallFunction(0, "JulianDay", @z, 6, 2016)), 1)  ;2457569.5 - 2457539.5
Else
    MessageRequester("ERROR", "Can't open Library Astro2_0", #PB_MessageRequester_Ok)
EndIf
CloseLibrary(0)

; Results of the above Call are: (PREVIOUSLY)
; 
; 01/01/0001 - 1721422.5
; 30/04/2016 - 2457478.5
; 15/05/2016 - 2457508.5
; 31/05/2016 - 2457508.5
; 15/06/2016 - 2457539.5
; 30/06/2016 - 2457539.5

; Results of the above Call are: (AFTER CHANGE)
; 
; 01/01/0001 - 1721423.5
; 30/04/2016 - 2457508.5
; 15/05/2016 - 2457523.5
; 31/05/2016 - 2457539.5
; 15/06/2016 - 2457554.5
; 30/06/2016 - 2457569.5
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: Passing of variable to DLL not taking place

Post by DontTalkToMe »

I have to say: what a mess.

1. The code you posted for the DLL does not work as you posted it, cannot even be compiled.
GJ = "G" ???

2. About the last "fixed" code, if you pass a value as a pointer that requires changes in the DLL function, you didn't post the updated version of it so your question "is it ok now ?" cannot be answered.

3. CallFunction cannot return float/double nor pass them, so yes one way (not the only one) to solve the problem is to return a pointer to a global double and to pass pointers to doubles if that's really what you want. So let's say that's OK.

4. The proper way to do this is through prototypes, resulting in a clean and understandable code perfectly equivalent to the code you used in the example without the DLL. Why you are against them ? Certainly not because they are complicated. Not compared to this. If you would like an example of using them let us know.
Blurryan
User
User
Posts: 32
Joined: Sat Oct 13, 2007 2:08 pm
Location: Kazakhstan

Re: Passing of variable to DLL not taking place

Post by Blurryan »

Thanks @DontTalkToMe.

I was checking out what is the alternative to not using Prototypes.

Being not a very good programmer possibly the mess.

With prototypes although things become "neater", the length of a statement becomes huge when there are many variables being passed and becomes difficult to track the variables.
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: Passing of variable to DLL not taking place

Post by DontTalkToMe »

If you still want to avoid prototypes you could just pass to your proc a single pointer to a structure with all your data packed in that, both the input and output (or returned data).

At least you don't have all those peek/poke stuff and you can read and write doubles directly.

Personally I think it's still better and easy to manage than this.
Blurryan
User
User
Posts: 32
Joined: Sat Oct 13, 2007 2:08 pm
Location: Kazakhstan

Re: Passing of variable to DLL not taking place

Post by Blurryan »

Noted, thanks.
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: Passing of variable to DLL not taking place

Post by DontTalkToMe »

In any case, even if you are not gonna to use it, example on how using prototypes makes it more clear:

Code: Select all

; DLL.PB

EnableExplicit

ProcedureDLL.d JulianDay (d1.d, m.i, y.i)
    Protected a.i, b.i, dd.d, mm.i, yy.i, JulD.d
    Protected GJ$    
    dd = d1: mm = m: yy = y
    If yy > 1582: GJ$ = "G": EndIf
    If yy < 1582: GJ$ = "J": EndIf
    If yy = 1582
        If mm > 10: GJ$ = "G": EndIf
        If mm < 10: GJ$ = "J": EndIf
        If mm = 10
            If dd > 14: GJ$ = "G": EndIf
            If dd < 5 : GJ$ = "J": EndIf
        EndIf
    EndIf
    If mm > 2: mm = mm + 0: yy = yy + 0: ElseIf mm = 1 Or mm = 2: yy = yy - 1: mm = mm + 12: EndIf
    a = Int(yy / 100)
    If GJ$ = "J": b = 0: Else: b = 2 - a + Int(a / 4): EndIf
    JulD = Int(365.25 * (yy + 4716)) + Int(30.6001 * (mm + 1)) + dd + b - 1524.5
    ProcedureReturn JulD
EndProcedure

Code: Select all

; CLIENT.PB

EnableExplicit

Prototype.d JulianDay (d1.d, m.i, y.i) : Global JulianDay.JulianDay 

If OpenLibrary(0, "dll.dll")
    JulianDay = GetFunction(0, "JulianDay")
    
    Global x.d = 1, y.d = 15, z.d = 30, zz.d = 31
    
    Debug "01/01/0001 - " + JulianDay(x, 1, 1)     ;1721423.5 
    Debug "30/04/2016 - " + JulianDay(z, 4, 2016)  ;2457508.5 
    Debug "15/05/2016 - " + JulianDay(y, 5, 2016)  ;2457523.5 
    Debug "31/05/2016 - " + JulianDay(zz, 5, 2016) ;2457539.5 
    Debug "15/06/2016 - " + JulianDay(y, 6, 2016)  ;2457554.5 
    Debug "30/06/2016 - " + JulianDay(z, 6, 2016)  ;2457569.5 
Else
    MessageRequester("ERROR", "Can't open Library Astro2_0", #PB_MessageRequester_Ok)
EndIf
CloseLibrary(0)
Blurryan
User
User
Posts: 32
Joined: Sat Oct 13, 2007 2:08 pm
Location: Kazakhstan

Re: Passing of variable to DLL not taking place

Post by Blurryan »

Thanks DontTalkToMe for the Prototype example.

In some functions I am getting into about 12 to 15 variables and using Prototypes gets us all confused.

Let me work out a better example on my prototype "issue" and post it to the forum in the next week, so that you may have a look and suggest better procedure.

Am travelling and hence the delayed response
Post Reply