Simple 64-bit DLL for MC64

Questions about MultiCharts and user contributed studies.
Terabyte
Posts: 8
Joined: 06 Jun 2012

Simple 64-bit DLL for MC64

Postby Terabyte » 06 Jun 2012

I'm trying to get some very simple 64-bit DLL functions to work with MC64. Some of them work and other fail.

Does anyone have a working sample of a 64-bit DLL which works with MC64 that can do something very simple like simply adding two numbers? Any language is fine so that I can see the declarations. ex. C++, PureBasic, FreeBasic. Please only submit tested 64-bit DLL code. I can get it to work fine with 32-bit DLL but not with 64-bit version.

Here's a snippet of the code that FAILS in the 64-bit DLL (works fine when compiled as 32-bit with TS9):

Code: Select all

; Prototype for Adding two numbers
ProcedureDLL.double AddDouble(num1.double , num2.double )
  Protected Mysum.double
  Mysum = num1 + num2
  ProcedureReturn Mysum
EndProcedure


Here is my MC64 test code:

Code: Select all

DefineDLLFunc: "DLLSample64.dll", LONG, "AddLong", LONG, LONG;
DefineDLLFunc: "DLLSample64.dll", float, "AddFloat", float, float;
DefineDLLFunc: "DLLSample64.dll", double, "AddDouble", double, double;
DefineDLLFunc: "DLLSample64.dll", int, "AddInt", int, int;
DefineDLLFunc: "DLLSample64.dll", void, "Mult2xRefFloat", LPFLOAT, LPFLOAT;
DefineDLLFunc: "DLLSample64.dll", void, "Mult2xRefDouble", LPDOUBLE, LPDOUBLE;

If Currentbar = 10 then begin
   Print( "- - - ",currentdate:0:0, ", ", currentTime:0:0, " - - -");
   // WORKS
   Value1 = AddLong(5,7);
   Print("AddLong performs 5+7=12, Actual = ",value1);
   
   // FAILS
   Value1 = AddFloat(float 3.14,float 2.15);
   Print("AddFloat performs 3.14+2.15=5.29, Actual = ",Value1);
   
   // FAILS
   Value1 = AddDouble(4.14, 5.15);
   Print("AddDouble performs 4.14+5.15=9.29, Actual = ",Value1);

   // WORKS
   Value1 = AddInt(4,3);
   Print("AddInt performs 4+3=7, Actual = ",value1);

   // FAILS
   Value1 =  5.6;
   Value2 =  6.7;
   Mult2xRefFloat(&Value1, &Value2);
   Print("Mult2xRefFloat performs 2 x Value2=11.2, 2 x Value3=13.4, Actual= ",Value1,", ", Value2);

   // WORKS
   Value1 = 1.2;
   Value2 = 3.3;
   Mult2xRefDouble(&Value1 , &Value2 );
   Print("Mult2xRefDouble performs 2 x Value2=2.4, 2 x Value3=6.6, Actual= ",Value1 ,", ", Value2 );
end; 



Thank you.

User avatar
Henry MultiСharts
Posts: 8447
Joined: 25 Aug 2011
Has thanked: 1207 times
Been thanked: 2704 times

Re: Simple 64-bit DLL for MC64

Postby Henry MultiСharts » 08 Jun 2012

Hello Terabyte,

We suppose that floating point calculations are compiled incorrectly for 64 bit by PureBasic compiler. As a workaround, you can try to avoid using floats in your code.

Terabyte
Posts: 8
Joined: 06 Jun 2012

Re: Simple 64-bit DLL for MC64

Postby Terabyte » 08 Jun 2012

It is also doubles that fail.

Do you have a C++ example demonstrating that MC64 works with a 64-bit DLL using doubles and floats? I would greatly appreciate it because then I can apply the technique that you use in C++ to PureBasic.

Here are the one's that I need because they don't work for me.

Code: Select all

DefineDLLFunc: "DLLSample64.dll", float, "AddFloat", float, float;
DefineDLLFunc: "DLLSample64.dll", double, "AddDouble", double, double;
DefineDLLFunc: "DLLSample64.dll", void, "Mult2xRefFloat", LPFLOAT, LPFLOAT;


Where :
AddFloat returns the sum of the two floats.
AddDouble returns the sum of the two doubles.
Mult2XRefFloat multiplies the two variables passed by pointer.

I think other developers will benefit from this knowledge as well.

Thank you!
Thank you very much!

Emmanuel
Posts: 287
Joined: 21 May 2009
Has thanked: 68 times
Been thanked: 19 times

Re: Simple 64-bit DLL for MC64

Postby Emmanuel » 09 Jun 2012

Hi Tera,

PureBasic V 4.6 have a known bug regarding DLL function returning double in 64 bits.

It work for Integer but not with single and double. (it return 2* time the first argument as I remember)

Purebasic did an update purebasic V 4.61in may, this bug should be solved.

I reported this bug to purebasic last year.

Be aware, that V 4.6 , have as well a limitation with array size above
array(3,62,1000000),

if you use array above this size , your dll won't produce any error message when you write in it but when you read back your array, it will give incorrect information.

Maybe this bug is solved with 4.61 purebasic.

Be carreful as well between, MC and purebasic 32/64, or MC and powerbasic 32, sending and reading string argument. String information are not accurate all the time.

Emmanuel

Terabyte
Posts: 8
Joined: 06 Jun 2012

Re: Simple 64-bit DLL for MC64

Postby Terabyte » 09 Jun 2012

Emmanuel, thank you very much for the tip on PB64 v4.61. That has solved part of the problem and I'm hoping you will share your expertise to solve the remaining problem.

Here's the current output from the test:

- - - 1120609, 1006 - - -
AddLong performs 5+7=12, Actual = 12.00
--> AddFloat performs 3.14+2.15=5.29, Actual = 3.14 <-- WRONG
--> AddDouble performs 4.14+5.15=9.29, Actual = 4.14 <--WRONG
AddInt performs 4+3=7, Actual = 7.00
Mult2xRefFloat performs 2 x Value2=11.2, 2 x Value3=13.4, Actual= 11.20, 13.40
Mult2xRefDouble performs 2 x Value2=2.4, 2 x Value3=6.6, Actual= 2.40, 6.60

Now the following are behaving correctly: AddLong, AddInt, Mult2xRefFloat and Mult2xRefDouble.

PROBLEM:
The problem remains that the AddFloat and AddDouble are failing. They both seem to be passing back the first parameter rather than the sum.

I'm hoping you may have some insight. Thank you again for your help.

Emmanuel
Posts: 287
Joined: 21 May 2009
Has thanked: 68 times
Been thanked: 19 times

Re: Simple 64-bit DLL for MC64

Postby Emmanuel » 09 Jun 2012

Hi

1/ Is your purebasic V 4.60 or V 4.61 ?

2/ Can you post the purebasic example ? so I can look for a solution for

--> AddFloat performs 3.14+2.15=5.29, Actual = 3.14 <-- WRONG
--> AddDouble performs 4.14+5.15=9.29, Actual = 4.14 <--WRONG

I had the same problem with purebasic V 4.60 , this is Purebasic bug

If is still not working with V 4.61, please let them know that this bug is still not
solve

http://www.purebasic.com/support.php


I was hoping Purebasic would solve this bug by now with V 4.61

Emmanuel

Terabyte
Posts: 8
Joined: 06 Jun 2012

Re: Simple 64-bit DLL for MC64

Postby Terabyte » 09 Jun 2012

Hi Emmanuel,

Here is my PureBasic x64 v4.61 code:

Code: Select all

EnableExplicit

#DebugLog = 1               ; Off=0,  On=1

Procedure PrintToFile( MyOut.s)
  Define Tempstr.s
  Define FileNum.l
 
    FileNum = OpenFile (#PB_Any,"c:\IEC_Log.txt")
    If FileNum > 0
      FileSeek(FileNum, Lof(FileNum))   
      Tempstr=  FormatDate("%yyyy-%mm-%dd, %hh:%ii:%ss:", Date() ) + ": " + MyOut
      WriteStringN(FileNum, Tempstr)
      CloseFile(FileNum)
    EndIf
   
    CompilerIf #DebugLog
        OutputDebugString_("PrintToFile: " + Tempstr)
    CompilerEndIf
EndProcedure

; These 4 procedures are Windows specific
;

; This procedure is called once, when the program loads the library
; for the first time. All init stuffs can be done here (but not DirectX init)
;
ProcedureDLL AttachProcess(Instance)
EndProcedure


; Called when the program release (free) the DLL
;
ProcedureDLL DetachProcess(Instance)
EndProcedure


; Both are called when a thread in a program call or release (free) the DLL
;
ProcedureDLL AttachThread(Instance)
EndProcedure

ProcedureDLL DetachThread(Instance)
EndProcedure

;
; Real code start here..
;

ProcedureDLL.l AddLong(num1.l, num2.l)
  Protected Mysum.l
  Mysum = num1 + num2
  ProcedureReturn Mysum
EndProcedure

ProcedureDLL.f AddFloat(num1.f, num2.f)
  Protected Mysum.f 
  Mysum = num1 + num2
  CompilerIf #DebugLog=1
    PrintToFile("v20120609-1417 AddFloat:" + StrF(Num1) + " + " + StrF(Num2) + " = " + StrF(mysum) + ", PeekL=" + Str(PeekL(@MySum)))
  CompilerEndIf

  ProcedureReturn PeekL(@Mysum)
EndProcedure

ProcedureDLL.d AddDouble(num1.d, num2.d)
  Protected Mysum.d
  Mysum = num1 + num2
  CompilerIf #DebugLog=1
    PrintToFile("AddDouble:" + StrD(Num1) + " + " + StrD(Num2) + " = " + StrD(mysum) + ", PeekL=" + Str(PeekL(@MySum)))
  CompilerEndIf

  ProcedureReturn PeekL(@Mysum)
EndProcedure


ProcedureDLL.i AddInt(num1.i, num2.i)
  Protected Mysum.i
  Mysum = num1 + num2
  ProcedureReturn Mysum
EndProcedure


ProcedureDLL Mult2xRefFloat(*num1.Float, *num2.Float)
  *num1\f = (*num1\f) * 2.0
  *num2\f = (*num2\f) * 2.0
EndProcedure

ProcedureDLL Mult2xRefDouble(*num1.Double, *num2.Double)
  *num1\d = (*num1\d) * 2.0
  *num2\d = (*num2\d) * 2.0
EndProcedure



Here is the output from the log:
2012-06-09, 14:19:26:: v20120609-1417 AddFloat:3.1400001049 + 2.1500000954 = 5.2899999619, PeekL=1084835758
2012-06-09, 14:19:26:: AddDouble:4.1400000000 + 5.1500000000 = NaN, PeekL=0

I'll report it to PureBasic. Thanks for your expertise.

Emmanuel
Posts: 287
Joined: 21 May 2009
Has thanked: 68 times
Been thanked: 19 times

Re: Simple 64-bit DLL for MC64

Postby Emmanuel » 11 Jun 2012

Hi Tera,

It is clear, that purebasic still didn't solve this bug again, they promisse to correct the problem the 26th January 2012,

The only solution I have, is to return an integer instead :

in the function : (multiplying the float by 10000 for example)

Protected Mysum.l
Mysum = (num1 + num2)*10000

then, in easylanguage , dividing the integer by 10000.

Like that you will still have the solution. using an integer function

I would prefer that purebasic solve this bug, but I can not lose time waiting and waiting.

after the development of Purebasic,

Purebasic, will probably solve this bug soon if we report it.

Please report this bug now.

On my side, I am reporting this bug again.

Emmanuel


Return to “MultiCharts”