Page 1 of 2

A tool for programming a wrapper

Posted: Sat Feb 11, 2012 10:51 pm
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

Re: A tool for programming a wrapper

Posted: Sat Feb 11, 2012 11:26 pm
by IdeasVacuum
.....extremely efficient, tested with a 'big' DLL, very good pbi file. Thanks for sharing!

Re: A tool for programming a wrapper

Posted: Sun Feb 12, 2012 10:47 am
by kernadec
Hi, Infratec
very cool ...
thank you for sharing

Re: A tool for programming a wrapper

Posted: Sun Feb 12, 2012 7:52 pm
by Kwai chang caine
My first try obviously...... Kernel32 and User32...all done :D
Thanks for sharing 8)

Re: A tool for programming a wrapper

Posted: Sun Feb 12, 2012 8:15 pm
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

Re: A tool for programming a wrapper

Posted: Sun Feb 12, 2012 8:27 pm
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)

Re: A tool for programming a wrapper

Posted: Sun Feb 12, 2012 8:47 pm
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)

Re: A tool for programming a wrapper

Posted: Sun Feb 12, 2012 11:48 pm
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:

Re: A tool for programming a wrapper

Posted: Mon Feb 13, 2012 12:03 am
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

Re: A tool for programming a wrapper

Posted: Mon Feb 13, 2012 8:54 am
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

Re: A tool for programming a wrapper

Posted: Mon Feb 13, 2012 9:12 am
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

Re: A tool for programming a wrapper

Posted: Mon Feb 13, 2012 10:01 am
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

Re: A tool for programming a wrapper

Posted: Mon Feb 13, 2012 10:07 am
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!

Re: A tool for programming a wrapper

Posted: Mon Feb 13, 2012 10:31 am
by infratec
Hi,

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

Bernd

Re: A tool for programming a wrapper

Posted: Tue Feb 14, 2012 4:08 pm
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.