A tool for programming a wrapper

Share your advanced PureBasic knowledge/code with the community.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

A tool for programming a wrapper

Post by infratec »

Hi,

now I had to make my 5th wrapper and it is a lot of stupid typing. :cry:
So I thouhgt about a tool to do the 'stupid' part of the work.

Save it as MakeWrapper.pb

Code: Select all

;
; MakeWrapper
;
; by BKK (infratec), ts-soft
;

#Version$ = "1.04"

#WithTest = #True


Procedure.i MakeWrapper(Filename$, Array Functions.s(1))
  
  Result = #False
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      WrapperFile$ = Left(Filename$, Len(Filename$) - 3) + "pbi"
    CompilerDefault
      WrapperFile$ = GetFilePart(Filename$)
      WrapperFile$ = Left(WrapperFile$, FindString(WrapperFile$, ".") - 1)
      WrapperFile$ = Left(Filename$, FindString(Filename$, WrapperFile$) + Len(WrapperFile$) - 1) + ".pbi"
  CompilerEndSelect
  Wrapper = CreateFile(#PB_Any, WrapperFile$)
  If Wrapper
    LibName$ = ReplaceString(GetFilePart(WrapperFile$), ".pbi", "")
    WriteStringN(Wrapper, ";")
    WriteStringN(Wrapper, "; " + LibName$)
    WriteStringN(Wrapper, ";")
    WriteStringN(Wrapper, "; a wrapper for " + GetFilePart(Filename$))
    WriteStringN(Wrapper, ";")
   
    WriteStringN(Wrapper, "")
    WriteStringN(Wrapper, "")
   
    WriteStringN(Wrapper, "CompilerSelect #PB_Compiler_OS")
    WriteStringN(Wrapper, "  CompilerCase #PB_OS_Windows")
    WriteStringN(Wrapper, "    Global " + LibName$ + "_Filename$ = " + #DQUOTE$ + GetFilePart(Filename$) + #DQUOTE$)
    WriteStringN(Wrapper, "    Macro OSPrototype")
    WriteStringN(Wrapper, "      Prototype")
    WriteStringN(Wrapper, "    EndMacro")
    WriteStringN(Wrapper, "  CompilerCase #PB_OS_Linux")
    WriteStringN(Wrapper, "    Global " + LibName$ + "_Filename$ = " + #DQUOTE$ + ReplaceString(GetFilePart(WrapperFile$), ".pbi", ".so") + #DQUOTE$)
    WriteStringN(Wrapper, "    Macro OSPrototype")
    WriteStringN(Wrapper, "      PrototypeC")
    WriteStringN(Wrapper, "    EndMacro")
    WriteStringN(Wrapper, "  CompilerCase #PB_OS_MacOS")
    WriteStringN(Wrapper, "    Global " + LibName$ + "_Filename$ = " + #DQUOTE$ + ReplaceString(GetFilePart(WrapperFile$), ".pbi", ".so") + #DQUOTE$)
    WriteStringN(Wrapper, "    Macro OSPrototype")
    WriteStringN(Wrapper, "      PrototypeC")
    WriteStringN(Wrapper, "    EndMacro")
    WriteStringN(Wrapper, "CompilerEndSelect")
   
    WriteStringN(Wrapper, "")
    WriteStringN(Wrapper, "")
   
    For i = 0 To ArraySize(Functions())
      WriteStringN(Wrapper, "OSPrototype.i Proto_" + Functions(i)  + "()")
    Next i
   
    WriteStringN(Wrapper, "")
    WriteStringN(Wrapper, "")
   
    For i = 0 To ArraySize(Functions())
      WriteStringN(Wrapper, "Global " + Functions(i)  + ".Proto_" + Functions(i))
    Next i
   
    WriteStringN(Wrapper, "")
    WriteStringN(Wrapper, "")
   
    WriteStringN(Wrapper, "Global " + LibName$ + ".i")
   
    WriteStringN(Wrapper, "")
    WriteStringN(Wrapper, "")
   
   
    WriteStringN(Wrapper, "Procedure.i " + LibName$ + "_LibInit()")
    WriteStringN(Wrapper, "  ")
    WriteStringN(Wrapper, "  Result = #False")
    WriteStringN(Wrapper, "  ")
    WriteStringN(Wrapper, "  " + LibName$ + " = OpenLibrary(#PB_Any, " + LibName$ + "_Filename$" + ")")
    WriteStringN(Wrapper, "  if " + LibName$)
    For i = 0 To ArraySize(Functions())
      WriteStringN(Wrapper, "    " + Functions(i)  + " = GetFunction(" + LibName$ + ", " + #DQUOTE$ + Functions(i) + #DQUOTE$ + ")")
      CompilerIf #WithTest
        WriteStringN(Wrapper, "    If " + Functions(i) + " = #Null : Result + 1 : EndIf")
      CompilerEndIf
    Next i
    WriteStringN(Wrapper, "    ")
    WriteStringN(Wrapper, "    If Result = #False")
    WriteStringN(Wrapper, "      Result = #True")
    WriteStringN(Wrapper, "    Else")
    WriteStringN(Wrapper, "      Result = #False")
    WriteStringN(Wrapper, "    EndIf")
    WriteStringN(Wrapper, "  EndIf")
    WriteStringN(Wrapper, "  ")
    WriteStringN(Wrapper, "  ProcedureReturn Result")
    WriteStringN(Wrapper, "")
    WriteStringN(Wrapper, "EndProcedure")
   
    WriteStringN(Wrapper, "")
    WriteStringN(Wrapper, "")
   
    WriteStringN(Wrapper, "Procedure " + LibName$ + "_LibFree()")
    WriteStringN(Wrapper, "  If IsLibrary(" + LibName$ + ") : CloseLibrary(" + LibName$ + ") : EndIf")
    WriteStringN(Wrapper, "  " + LibName$ + " = 0")
    WriteStringN(Wrapper, "EndProcedure")
   
    CloseFile(Wrapper)
   
    Result = #True
  EndIf
 
  ProcedureReturn Result
 
EndProcedure


CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    Filename$ = OpenFileRequester("Select the library file", "", "Libraries|*.dll;*.ocx;*.drv;*.cpl;*.sys", 0)
  CompilerDefault
    Filename$ = OpenFileRequester("Select the library file", "", "Libraries (lib*)|lib*", 0)
CompilerEndSelect
If Filename$
  Library = OpenLibrary(#PB_Any, Filename$)
  If Library
    FunctionCount = CountLibraryFunctions(Library)
    Dim Function.s(FunctionCount - 1)
    If ExamineLibraryFunctions(Library)
      i = 0
      While NextLibraryFunction()
        Function(i) = LibraryFunctionName()
        i + 1
      Wend
      If MakeWrapper(Filename$, Function())
        Text$ = "A skeleton of the wrapper exists now." + #LF$
        Text$ + "But you still have to edit the filename" + #LF$
        Text$ + "and the prototypes of the functions." + #LF$
        Text$ + #LF$
        Text$ + "Good luck !"
        MessageRequester("Info", Text$)
      EndIf
    EndIf
    CloseLibrary(Library)
  EndIf
EndIf
Maybe it is usefull for others.

Bernd
Last edited by infratec on Mon Feb 13, 2012 10:30 am, edited 4 times in total.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: A tool for programming a wrapper

Post by IdeasVacuum »

.....extremely efficient, tested with a 'big' DLL, very good pbi file. Thanks for sharing!
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
kernadec
Enthusiast
Enthusiast
Posts: 146
Joined: Tue Jan 05, 2010 10:35 am

Re: A tool for programming a wrapper

Post by kernadec »

Hi, Infratec
very cool ...
thank you for sharing
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: A tool for programming a wrapper

Post by Kwai chang caine »

My first try obviously...... Kernel32 and User32...all done :D
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A tool for programming a wrapper

Post by infratec »

Kwaï chang caïne wrote:My first try obviously...... Kernel32 and User32...all done :D
Nothing done :!:

Don't forget:
The program only gives you a 'compilable' skelleton.

You still have to modify all prototype declarations.
(the parameters and the return value)

The program only saves you the manual typing of all the other stuff.

Bernd
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: A tool for programming a wrapper

Post by Kwai chang caine »

Yes yes, don't worry INFRATEC, i have understand

In fact i'm a little bit mistaked in the english word "Done" :oops:
I want to say, all is good...or that's works all :D

Thanks again for your great job 8)
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A tool for programming a wrapper

Post by infratec »

Hi,

as usual: I found a bug :!:

The global filename of the dll file was fixed to LibSSH2_Filename$
(Forgot to replace it :oops: )

I also added a flag to include a test:

Code: Select all

#WithTest = #True
If it is true, all functions are checked if they are really available in the dll.
Don't know if this makes sense, since the functions were already found.
But if the 'enduser' uses an other version of the dll it detects if still all functions are available or not.
...LibInit() returns false if not all functions were found.

Bernd

P.S.: I changed the code above (V1.01)
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A tool for programming a wrapper

Post by infratec »

Oh....

maybe I reinvent the wheel: http://www.purebasic.fr/english/viewtop ... 27&t=45226

Didn't know this before. :oops: :oops: :oops:
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: A tool for programming a wrapper

Post by ts-soft »

infratec wrote:Oh....

maybe I reinvent the wheel: http://www.purebasic.fr/english/viewtop ... 27&t=45226

Didn't know this before. :oops: :oops: :oops:
No problem, your code is opensource and some people only willing to use opensource :wink:

Greetings - Thomas
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
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A tool for programming a wrapper

Post by infratec »

Hi,

updated the code to V1.02 :!:

Now it's crossplatform compatible.
(I'm not able to test it on Mac OS X :cry: )

Bernd
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: A tool for programming a wrapper

Post by ts-soft »

Hello Bernd,
Good one!

You can shorten the first part with Compilerdirective to:

Code: Select all

WrapperFile$ = GetFilePart(Filename$)
WrapperFile$ = Left(WrapperFile$, Len(WrapperFile$) - Len(GetExtensionPart(WrapperFile$))) + "pbi"
This is crossplattform.

Greetings - Thomas
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
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A tool for programming a wrapper

Post by infratec »

Hi Thomas,

yes, this way it's easier, but it was not what I want.
In linux you have always symbolic links like libz.so -> libz.so.1.2.4
If someone choose the 'real' file GetFileExtension() only cuts .4

My version comes from the front and cuts always after the first point -> libz

Btw. updated the version to 1.03.

Bernd
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: A tool for programming a wrapper

Post by ts-soft »

Yes Bernd, you are right!

But on windows, not all DLLs have the extension "DLL": "OCX", "DRV", "CPL" or "SYS" are DLLs :wink:
I think on windows, you can use my version!
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
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A tool for programming a wrapper

Post by infratec »

Hi,

updated the code to V1.04.
Now also the files which Thomas mentioned are selectable.

Bernd
User avatar
michel51
Enthusiast
Enthusiast
Posts: 290
Joined: Mon Nov 21, 2005 10:21 pm
Location: Germany

Re: A tool for programming a wrapper

Post by michel51 »

Hi infratec,

I tested the code on Mac, but I get an error in line 128, "CountLibraryFunctions() is not a function, array, macro or linked list".
A look into the help told me, its right, This command is only on WINDOWS / LINUX available.

Don't know, how to solve this counting on Mac.
michel51

Mac OS X Snow Leopard (10.6.8 ) Intel
PureBasic V 5.21(x64), V 5.22beta
Post Reply