[Implemented] Advanced library handling in PB!

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Lebostein
Addict
Addict
Posts: 826
Joined: Fri Jun 11, 2004 7:07 am

[Implemented] Advanced library handling in PB!

Post by Lebostein »

Hi,

in PureBasic it's very laborious to write a cross platform application with using DLL's. Why? The reason is the separation of CallFunction()/CallFunctionFast() and CallCFunction()/CallCFunctionFast(). For example a wrapper for the FMOD-Library. For Windows-Version I must use "CallFunction()", for Linux I must use "CallCFunction()". So I must check the OS in every procedure. Very annoying:

Code: Select all

Procedure FMOD_FSOUND_Init(Sampling, Channels, Flags)
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    ProcedureReturn CallFunction(#Library, "FSOUND_Init", Sampling, Channels, Flags)
  CompilerElse
    ProcedureReturn CallCFunction(#Library, "FSOUND_Init", Sampling, Channels, Flags)
  CompilerEndIf
EndProcedure

Procedure FMOD_FSOUND_Sample_Load(SampleIndex, SourceFile$)
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  	ProcedureReturn CallFunction(#Library, "FSOUND_Sample_Load", SampleIndex, SourceFile$, 0, 0, 0)
  CompilerElse
  	ProcedureReturn CallCFunction(#Library, "FSOUND_Sample_Load", SampleIndex, SourceFile$, 0, 0, 0)
  CompilerEndIf
EndProcedure

....

My idea: A new function "LibraryMode(mode)" like "DrawingMode(mode)" for example. Now you can set the mode in the first lines of your program or every time, when you want . For example:

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
	LibraryMode(#PB_Library_STDCALL)
CompilerElse
	LibraryMode(#PB_Library_CDECL)
CompilerEndIf

Procedure FMOD_FSOUND_Init(Sampling, Channels, Flags)
	ProcedureReturn CallFunction(#Library, "FSOUND_Init", Sampling, Channels, Flags)
EndProcedure

Procedure FMOD_FSOUND_Sample_Load(SampleIndex, SourceFile$)
	ProcedureReturn CallFunction(#Library, "FSOUND_Sample_Load", SampleIndex, SourceFile$, 0, 0, 0)
EndProcedure

....

The functions CallCFunction()/CallCFunctionFast() are needless now.

An other idea is for example to set the mode by loading: OpenLibrary(#Library, filename$, mode)

What do you think about it? Other ideas? In BlitzBasic, for example, the library mode (STDCALL/CDECL) was detected automatically...
Lebostein
Addict
Addict
Posts: 826
Joined: Fri Jun 11, 2004 7:07 am

Post by Lebostein »

No ideas, wishes or comments?
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

If your making heavy use of external libraries your much better off importing them using the library importer in the Library SDK folder.

That way you just get to call the library as if its an internal PB command.
FloHimself
Enthusiast
Enthusiast
Posts: 229
Joined: Wed May 14, 2003 3:38 pm
Location: Lüneburg - Germany

Post by FloHimself »

two easy workarounds:
- recompile the DLL on windows with cdecl convention
or
- generate the wrapper by a script or something.
My favorite numbers: 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Post by Polo »

FloHimself wrote:two easy workarounds:
- recompile the DLL on windows with cdecl convention
or
- generate the wrapper by a script or something.
He's not asking for workaround but for new commands and command changes ;)
FloHimself
Enthusiast
Enthusiast
Posts: 229
Joined: Wed May 14, 2003 3:38 pm
Location: Lüneburg - Germany

Post by FloHimself »

I read his post carefully and noticed this.
I wanted to help him to go forward with his FMOD wrappers
and i think my previous post is just a try to help.

In this case it is just unnecessary to change any functions.

But this is just my opinion and suggestion. You don't have to
agree here. ;)
My favorite numbers: 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
Dummy
Enthusiast
Enthusiast
Posts: 162
Joined: Wed Jun 09, 2004 11:10 am
Location: Germany
Contact:

Re: Advanced library handling in PB!

Post by Dummy »

Lebostein wrote:A new function "LibraryMode(mode)" like "DrawingMode(mode)" for example.
Noooooooooo!

That would Slow the CallFunctionFast() command(used to call non dll functions by pointer, too) down!!!
PureBasic has a veeeeeeeery good performance compared to other languages - please never change that!

Please not!
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

This is why we need macro support.

CompilerIf #PB_OS = #PB_Windows
MYCALLFUNCTION = "CallFunction"
CompilerElse
MYCALLFUNCTION = "CallCFunction"
CompilerEndif


Then you could just call your function as MYCALLFUNCTION(blah, blah...)

[edit]
If you don't care about the overhead, why not make a procedure that wraps CallFunction or CallCFunction based on the OS and just call the wrapper?

Code: Select all

Procedure.l CallFunctionOS(blah,blah...)
  CompilerIf Pb_os = #pb_win
  CallFunction(blah,blah...)
  CompilerElse
  CallCFunction(blah,blah...)
  CompilerEndIf
EndProcedure
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

dracflamloc wrote:This is why we need macro support.

CompilerIf #PB_OS = #PB_Windows
MYCALLFUNCTION = "CallFunction"
CompilerElse
MYCALLFUNCTION = "CallCFunction"
CompilerEndif
Hehe, I didn't dare writing that. :P
Good programmers don't comment their code. It was hard to write, should be hard to read.
FloHimself
Enthusiast
Enthusiast
Posts: 229
Joined: Wed May 14, 2003 3:38 pm
Location: Lüneburg - Germany

Post by FloHimself »

dracflamloc wrote:This is why we need macro support.
good idea. you can use fasm macros. maybe something like this could
work? i haven't tested this.

Code: Select all

!macro callproc proc,[arg]
!{
  !reverse PUSH arg
  !common CALL proc
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  !forward ADD ESP, 4
  CompilerEndIf
!}

[... opendll ...]
*funcPtr = IsFunction("foobar")
!callproc [p_funcPtr], param1, param2
!MOV [v_RetVal], EAX
dracflamloc wrote: If you don't care about the overhead, why not make a procedure that wraps CallFunction or CallCFunction based on the OS and just call the wrapper?

Code: Select all

Procedure.l CallFunctionOS(blah,blah...)
  CompilerIf Pb_os = #pb_win
  CallFunction(blah,blah...)
  CompilerElse
  CallCFunction(blah,blah...)
  CompilerEndIf
EndProcedure
because PB doesn't support variable arguments for procedures, you would
have to write your "CallFunctionsOS" procedure for each parameter count.
My favorite numbers: 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

>>because PB doesn't support variable arguments for procedures, you would
>>have to write your "CallFunctionsOS" procedure for each parameter count.
Use TailBite, change in the Desc the parameters to Any. :wink:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Dummy
Enthusiast
Enthusiast
Posts: 162
Joined: Wed Jun 09, 2004 11:10 am
Location: Germany
Contact:

Post by Dummy »

ts-soft wrote:>>because PB doesn't support variable arguments for procedures, you would
>>have to write your "CallFunctionsOS" procedure for each parameter count.
Use TailBite, change in the Desc the parameters to Any. :wink:
Not applicable for Linux, since Tailbite is Windows only :wink:
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

A little mistake of me Image
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Post Reply