Author Topic: Using a O2 DLL with apps generated with other compilers  (Read 18551 times)

0 Members and 1 Guest are viewing this topic.

Charles Pegge

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #15 on: January 11, 2011, 01:14:09 PM »
Try putting an asterisk to the left of each param :)

forum ref:
http://forum.purebasic.com/english/viewtopic.php?f=13&t=41893

Peter

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #16 on: January 11, 2011, 01:22:46 PM »
Hi Charles,

making of Dll's is great!
good work!

here is a Demo
Code: [Select]
indexbase 0
include "win_c.inc"
include "win_g.inc"

Declare Function DrawCircle  Lib "Draws.dll" (byval hdc as long, byval x as long, byval y as long, byval r as long, byval color as long)
Declare Function DrawBox     Lib "Draws.dll" (byval hdc as long, byval x1 as long,byval y1 as long,byval x2 as long,byval y2 as long,byval color as long)
Declare Function DrawEllipse Lib "Draws.dll" (byval hdc as long, byval mx as long,byval my as long,byval r1 as long,byval r2 as long,byval color as long)
Declare Function DrawLine    Lib "Draws.dll" (byval hdc as long, byval x2 as long,byval y2 as long,byval x3 as long,byval y3 as long,byval color as long)

Dim hdc as long
SetWindow "Dll-Demo / OxygenBasic Version o26",800,600,ws_overlapped
hdc = setbuffer winwidth,winheight

while winexit =0
ClearBuffer
DrawCircle  hdc,50,50,40,&HB0B0B0
DrawCircle  hdc,740,50,40,&HA0A0A0
DrawBox     hdc,10,10,768,780,255*34825
For jx=0 To 49
DrawEllipse hdc,250,300,200+jx,150-jx, &H80FF80*jx
DrawEllipse hdc,620,300,150-jx,200+jx, &HFF80FF*jx
Next
DoEvents
FlipBuffer
Wend
CloseApp 


Peter

.

Charles Pegge

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #17 on: January 11, 2011, 01:36:21 PM »
Nice one Peter!

I'm going to work on RTL64 as soon as I have done the dreaded annual tax returns.

Does anybody not have a 64 bit OS?

Charles

Peter

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #18 on: January 11, 2011, 01:40:31 PM »

don't pay any tax, buy computer's!

Peter

efgee

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #19 on: January 11, 2011, 02:26:46 PM »
Does anybody not have a 64 bit OS?

Here we have:

WinXP_32-SP3
Vista_32-SP2
Win7_64
« Last Edit: January 11, 2011, 02:57:17 PM by efgee »

efgee

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #20 on: January 11, 2011, 03:04:19 PM »
Try putting an asterisk to the left of each param :)

Doing a manual byRef with an asterik like that:

Code: [Select]
Define *a.l = 4
Define *b.l = 2

Debug IsInitialized()
Debug MathAdd(*a,*b)
Debug MathDiv(4,2)
Debug MathMul(4,2)
Debug MathSub(4,2)

doesn't change a thing, it still crashes.

I suppose the PureBasic compiler is clever enough and treats params used by imported functions always byRef because the error message does not change...

JRS

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #21 on: January 11, 2011, 10:02:01 PM »
Quote
Does anybody not have a 64 bit OS?

I do but so does anyone else for pennies an hour. You can pretty much create any Windows (32/64) or Linux (32/64) on a Amazon S2 server instance. You only pay (.14 to .20 US cents / hour) and you can suspend the instance which cost you nothing while not in use. I just don't have that big of a need at the moment to go out and buy a 64 bit box when what I have works fine.

jack

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #22 on: January 12, 2011, 05:52:00 AM »
Code: [Select]
Define *a.l = 4
Define *b.l = 2

the asterisk means it's a pointer, but PureBasic treats pointers differently than C,
if I am not mistaken, the first two statements will set the pointer to point to memory location 4 and 2
not set the value of the variables as you intended, I will give it a shot and see what will work.

jack

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #23 on: January 12, 2011, 08:11:05 AM »
I finaly managed to compile the dll, first thing I noticed is that the exported functions have upper/lower case characters,
in PureBasic when you import a function it treats the name as lower case, you need to declare as follows
Code: [Select]
Import "g:\Bunion\examples\dll_math_o2.lib"
  IsInitialized()     As "_IsInitialized"
  MathAdd(n1.i, n2.i) As "_MathAdd"
  MathDiv(n1.i, n2.i) As "_MathDiv"
  MathMul(n1.i, n2.i) As "_MathMul"
  MathSub(n1.i, n2.i) As "_MathSub"
EndImport

when I run the example I get this error from PureBasic
Quote
The application failed to initialize properly (0xc0000005). Click on OK to terminate the application.
I will give it try in FreeBasic an see what happens.

Charles Pegge

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #24 on: January 12, 2011, 08:28:35 AM »
This is what I had in mind with regard to byref

PureBasic
Code: [Select]
Import "g:\Bunion\examples\dll_math_o2.lib"
  IsInitialized()
  MathMul(*n1.i, *n2.i)
  MathDiv(*n1.i, *n2.i)
  MathAdd(*n1.i, *n2.i)
  MathSub(*n1.i, *n2.i)
EndImport

jack

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #25 on: January 12, 2011, 09:20:41 AM »
I got to kind of work in FreeBasic

FreeBasic code
Code: [Select]
#inclib "dll_math_o2"

declare function IsInitialized cdecl alias "IsInitialized" () as integer
declare function MathAdd cdecl alias "MathAdd" (byref as integer, byref as integer) as integer
declare function MathDiv cdecl alias "MathDiv" (byref as integer, byref as integer) as integer
declare function MathMul cdecl alias "MathMul" (byref as integer, byref as integer) as integer
declare function MathSub cdecl alias "MathSub" (byref as integer, byref as integer) as integer

Print IsInitialized()
Print MathMul(4,2)
Print MathDiv(4,2)
Print MathAdd(4,2)
Print MathSub(4,2)

print "press return to end ";
sleep

output
Quote
1
 8             2  6
-2954414
press return to end

if I try to use stdcall the linker looks for functions with @bytes at the end of the function,
will see if I can resolve that.

efgee

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #26 on: January 12, 2011, 09:24:56 AM »
This is what I had in mind with regard to byref

PureBasic
Code: [Select]
Import "g:\Bunion\examples\dll_math_o2.lib"
  IsInitialized()
  MathMul(*n1.i, *n2.i)
  MathDiv(*n1.i, *n2.i)
  MathAdd(*n1.i, *n2.i)
  MathSub(*n1.i, *n2.i)
EndImport

Tried this yesterday (and different other variations...) but it crashes - not even the first function is called properly.

efgee

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #27 on: January 12, 2011, 09:31:22 AM »
@Jack
thank you for helping out, would have tried with FreeBasic myself today...

Have to give HotBasic a spin and see if it has problems too...

efgee

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #28 on: January 12, 2011, 09:34:33 AM »
Relocatability is achieved by avoiding absolute addresses completely. Addresses are referenced either relatively (for direct jumps and calls) or by offset from a register. EBX contains the absolute address of the .bssdata - the start of the uninitialised data section. All function tables and static variables are mapped out as an offset from this base.

How does register EBX obtain an absolute address to .bssdata at runtime? In 32 bit mode its a little awkward but this is what I do:
Code: [Select]
call fwd here
.here
pop ebx 'get the absolute address of here
sub ebx,here 'deduct virtual address of here
add ebx,bssdata 'add virtual address of bssdata

In 64 bit mode it's so much simpler:
Code: [Select]
lea rip rbx,bssdata 'load effective address (Relative to Instruction Pointer) .bssdata
(The notation will differ in other assemblers)

Didn't know this was even possible; I can't remember having seen such approach at all... until now.

 :)

jack

  • Guest
Re: Using a O2 DLL with apps generated with other compilers
« Reply #29 on: January 12, 2011, 11:51:19 AM »
here's the FreeBasic Program with run-time loading, it works as expected.
Code: [Select]
''
'' this program -- loads dll_math_o2 at runtime, calls a dll_math_o2's function and prints the result
''
'' note: requires the compiled dll_math_o2 dynamic library to be available in current directory
''

dim library as any ptr
dim IsInitialized as function () as integer
dim MathAdd as function ( byref operand1 as integer, byref operand2 as integer ) as integer
dim MathDiv as function ( byref operand1 as integer, byref operand2 as integer ) as integer
dim MathMul as function ( byref operand1 as integer, byref operand2 as integer ) as integer
dim MathSub as function ( byref operand1 as integer, byref operand2 as integer ) as integer

'' Note we specify just "dll_math_o2" as library file name; this is to ensure
'' compatibility between Windows and Linux, where a dynamic library
'' has different file name and extension.
''
library = dylibload( "dll_math_o2" )
if( library = 0 ) then
print "Cannot load the dll_math_o2 dynamic library, aborting program..."
end 1
end if

IsInitialized = dylibsymbol( library, "IsInitialized" )
if( IsInitialized = 0 ) then
print "Cannot get IsInitialized function address from dll_math_o2 library, aborting program..."
end 1
end if
   
MathAdd = dylibsymbol( library, "MathAdd" )
if( MathAdd = 0 ) then
print "Cannot get MathAdd function address from dll_math_o2 library, aborting program..."
end 1
end if

MathDiv = dylibsymbol( library, "MathDiv" )
if( MathDiv = 0 ) then
print "Cannot get MathDiv function address from dll_math_o2 library, aborting program..."
end 1
end if

MathMul = dylibsymbol( library, "MathMul" )
if( MathMul = 0 ) then
print "Cannot get MathMul function address from dll_math_o2 library, aborting program..."
end 1
end if

MathSub = dylibsymbol( library, "MathSub" )
if( MathSub = 0 ) then
print "Cannot get MathSub function address from dll_math_o2 library, aborting program..."
end 1
end if
   
randomize timer

dim as integer x = 4
dim as integer y = 2

    ' print x; " +"; y; " ="; MathAdd( x, y )
    Print "IsInitialized()="; IsInitialized()
    Print x; " *"; y; " ="; MathMul(4,2)
    Print x; " /"; y; " ="; MathDiv(x, y)
    Print x; " +"; y; " ="; MathAdd(x, y)
    Print x; " -"; y; " ="; MathSub(4,2)
'' Done with the library; the OS will automatically unload libraries loaded by a process
'' when it terminates, but we can also force unloading during our program execution to
'' save resources; this is what the next line does. Remember that once you unload a
'' previously loaded library, all the symbols you got from it via dylibsymbol will become
'' invalid, and accessing them will cause the application to crash.
''
dylibfree library
   
    print "press return to end ";
    sleep
have not figured out how to use an import lib because when I try to compile with stdcall the linker complains
"can't find function IsInitialized@0" and so on for the rest of the functions.
if I modify the def file like this
Quote
LIBRARY dll_math_o2.dll
EXPORTS
IsInitialized@0              @1
MathAdd@8                    @2
MathDiv@8                    @3
MathMul@8                    @4
MathSub@8                    @5
and then re-create the import lib, it compiles and links OK but when run it gives the error "can't find IsInitialized@0 in dll"