Page 1 of 3

Python 3.5.2 wrapper

Posted: Tue Nov 22, 2016 10:53 pm
by infratec
Hi,

since it was needed:

Save it as Python35.pbi

Code: Select all

;
; Python 3.5 for PureBASIC
;

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    Global Python_Libname$ = "python35.dll"
    Macro OSPrototype
      PrototypeC
    EndMacro
  CompilerCase #PB_OS_Linux
    Global Python_Libname$ = "python.so"
    Macro OSPrototype
      PrototypeC
    EndMacro
  CompilerCase #PB_OS_MacOS
    Global Python_Libname$ = "python.so"
    Macro OSPrototype
      PrototypeC
    EndMacro
CompilerEndSelect




Global PythonLib.i


Structure _typeobject Align #PB_Structure_AlignC
  *ob_base
  *tp_name            ; For printing, in format "<module>.<name>"
  tp_basicsize.l
  tp_itemsize.l       ; For allocation
  
  ; Methods To implement standard operations
  
  *tp_dealloc
  *tp_print
  *tp_getattr
  *tp_setattr
  *tp_reserved     ; formerly known as tp_compare
  *tp_repr
  
  ; Method suites For standard classes
  
  *tp_as_number
  *tp_as_sequence
  *tp_as_mapping
  
  ; More standard operations (here For binary compatibility)
  
  *tp_hash
  *tp_call
  *tp_str
  *tp_getattro
  *tp_setattro
  
  ; Functions To access object As input/output buffer
  *tp_as_buffer
  
  ; Flags To Define presence of optional/expanded features
  tp_flags.l;
  
  *tp_doc      ; Documentation string
  
  ; Assigned meaning in release 2.0
  ; call function For all accessible objects
  *tp_traverse
  
  ; delete references To contained objects
  *tp_clear;
  
  ; Assigned meaning in release 2.1
  ; rich comparisons
  *tp_richcompare
  
  ; weak reference enabler
  tp_weaklistoffset.l
  
  ; Iterators
  *tp_iter
  *tp_iternext
  
  ; Attribute descriptor And subclassing stuff
  *tp_methods
  *tp_members
  *tp_getset
  *tp_base
  *tp_dict
  *tp_descr_get
  *tp_descr_set
  *tp_dictoffset
  *tp_init
  *tp_alloc
  *tp_new
  *tp_free      ; Low-level free-memory routine
  *tp_is_gc     ; For PyObject_IS_GC
  *tp_bases
  *tp_mro      ; method resolution order
  *tp_cache
  *tp_subclasses
  *tp_weaklist
  *tp_del
  
  ; Type attribute cache version tag. Added in version 2.6
  tp_version_tag.u
  
  CompilerIf 1 = 0  ;COUNT_ALLOCS
                    ; these must be last And never explicitly initialized
    tp_allocs.l
    tp_frees.l
    tp_maxalloc.l
    *tp_prev
    *tp_next
  CompilerEndIf
EndStructure



Structure PythonObject Align #PB_Structure_AlignC
  *_ob_next
  *_ob_prev
  ob_refcnt.l
  *ob_type._typeobject
EndStructure


Macro Python_INCREF(op)
  op\ob_refcnt + 1
EndMacro

Macro Python_XINCREF(op)
  If op : Python_INCREF(op) : EndIf
EndMacro

Macro Python_DECREF(op)
  op\ob_refcnt - 1
  If op\ob_refcnt <> 0
    ; Don't know how to do it
  Else
    ; Don't know how to do it
  EndIf
EndMacro

Macro Python_XDECREF(op)
  If op : Python_DECREF(op) : EndIf
EndMacro

Macro Python_CLEAR()
  If op
    *_py_tmp = op
    op = #Null
    Py_DECREF(*_py_tmp)
  EndIf
EndMacro




OSPrototype.i Py_GetProgramFullPath()

OSPrototype.i Py_GetVersion()
OSPrototype.i Py_GetPlatform()
OSPrototype.i Py_GetCopyright()
OSPrototype.i Py_GetCompiler()
OSPrototype.i Py_GetBuildInfo()

OSPrototype Py_SetPythonHome(*String.p-Unicode)
OSPrototype.i Py_GetPythonHome()
OSPrototype Py_SetPath(*String.p-unicode)
OSPrototype.i Py_GetPath()
OSPrototype Py_SetProgramName(*String.p-Unicode)
OSPrototype.i Py_GetProgramName()

OSPrototype Py_Initialize()
OSPrototype Py_InitializeEx(initsigs.l)
OSPrototype Py_Finalize()

OSPrototype Py_IncRef(*PyObject)
OSPrototype Py_DecRef(*PyObject)

OSPrototype.i PyCallable_Check(*PyObject)

OSPrototype.l PyDict_GetItemString(*PyObject, String.p-Ascii)

OSPrototype PyErr_Print()
OSPrototype.l PyErr_Occurred()
OSPrototype PyErr_Clear()

OSPrototype.l PyImport_AddModule(String.p-Ascii)
OSPrototype.i PyImport_Import(*PyObject)

OSPrototype.l PyLong_AsLong(*PyObject)
OSPrototype.l PyLong_FromLong(Value.l)

OSPrototype.l PyModule_GetDict(*PyObject)

OSPrototype.l PyObject_GetAttrString(*PyObject, String.p-Ascii)
OSPrototype.l PyObject_CallObject(*PyObject1, *pyObject2)

OSPrototype.i PyRun_SimpleString(String.p-Ascii)

OSPrototype.l PyTuple_New(Len.l)
OSPrototype.i PyTuple_SetItem(*PyObject1, Size.l, *PyObject2)

OSPrototype.i PyUnicode_FromString(String.p-UTF8)
OSPrototype.i PyUnicode_FromObject(*PyObject)
OSPrototype.i PyUnicode_AsUnicode(*PyObject)

OSPrototype.i PyArg_Parse(*args, format.p-Ascii, *char)







Procedure.i PythonInit()
  
  PythonLib = OpenLibrary(#PB_Any, Python_Libname$)
  If PythonLib
    Global Pyth_GetProgramFullPath.Py_GetProgramFullPath = GetFunction(PythonLib, "Py_GetProgramFullPath")
    
    Global Pyth_GetVersion.Py_GetVersion = GetFunction(PythonLib, "Py_GetVersion")
    Global Pyth_GetPlatform.Py_GetPlatform = GetFunction(PythonLib, "Py_GetPlatform")
    Global Pyth_GetCopyright.Py_GetCopyright = GetFunction(PythonLib, "Py_GetCopyright")
    Global Pyth_GetCompiler.Py_GetCompiler = GetFunction(PythonLib, "Py_GetCompiler")
    Global Pyth_GetBuildInfo.Py_GetBuildInfo = GetFunction(PythonLib, "Py_GetBuildInfo")
    
    Global Python_SetPythonHome.Py_SetPythonHome = GetFunction(PythonLib, "Py_SetPythonHome")
    Global Pyth_GetPythonHome.Py_GetPythonHome = GetFunction(PythonLib, "Py_GetPythonHome")
    Global Python_SetPath.Py_SetPath = GetFunction(PythonLib, "Py_SetPath")
    Global Pyth_GetPath.Py_GetPath = GetFunction(PythonLib, "Py_GetPath")
    Global Python_SetProgramName.Py_SetProgramName = GetFunction(PythonLib, "Py_SetProgramName")
    Global Pyth_GetProgramName.Py_GetProgramName = GetFunction(PythonLib, "Py_GetProgramName")
    
    Global Python_Initialize.Py_Initialize = GetFunction(PythonLib, "Py_Initialize")
    Global Python_InitializeEx.Py_InitializeEx = GetFunction(PythonLib, "Py_InitializeEx")
    Global Python_Finalize.Py_Finalize = GetFunction(PythonLib, "Py_Finalize")
    
    Global Python_IncRef.Py_IncRef = GetFunction(PythonLib, "Py_IncRef")
    Global Python_DecRef.Py_DecRef = GetFunction(PythonLib, "Py_DecRef")
    
    Global PythonCallable_Check.PyCallable_Check = GetFunction(PythonLib, "PyCallable_Check")
    
    Global PythonDict_GetItemString.PyDict_GetItemString = GetFunction(PythonLib, "PyDict_GetItemString")
    
    Global PythonErr_Print.PyErr_Print = GetFunction(PythonLib, "PyErr_Print")
    Global PythonErr_Occurred.PyErr_Occurred = GetFunction(PythonLib, "PyErr_Occurred")
    Global PythonErr_Clear.PyErr_Clear = GetFunction(PythonLib, "PyErr_Clear")
    
    Global PythonImport_AddModule.PyImport_AddModule = GetFunction(PythonLib, "PyImport_AddModule")
    Global PythonImport_Import.PyImport_Import = GetFunction(PythonLib, "PyImport_Import")
    
    Global PythonLong_AsLong.PyLong_AsLong = GetFunction(PythonLib, "PyLong_AsLong")
    Global PythonLong_FromLong.PyLong_FromLong = GetFunction(PythonLib, "PyLong_FromLong")
    
    Global PythonModule_GetDict.PyModule_GetDict = GetFunction(PythonLib, "PyModule_GetDict")
    
    Global PythonObject_GetAttrString.PyObject_GetAttrString = GetFunction(PythonLib, "PyObject_GetAttrString")
    Global PythonObject_CallObject.PyObject_CallObject = GetFunction(PythonLib, "PyObject_CallObject")
    
    Global PythonRun_SimpleString.PyRun_SimpleString = GetFunction(PythonLib, "PyRun_SimpleString")
    
    Global PythonTuple_New.PyTuple_New = GetFunction(PythonLib, "PyTuple_New")
    Global PythonTuple_SetItem.PyTuple_SetItem = GetFunction(PythonLib, "PyTuple_SetItem")
    
    Global PythonUnicode_FromString.PyUnicode_FromString = GetFunction(PythonLib, "PyUnicode_InternFromString")
    Global PythonUnicode_FromObject.PyUnicode_FromObject = GetFunction(PythonLib, "PyUnicode_FromObject")
    Global PythonUnicode_AsUnicode.PyUnicode_AsUnicode = GetFunction(PythonLib, "PyUnicode_AsUnicode")
    
    Global PythonArg_Parse.PyArg_Parse = GetFunction(PythonLib, "PyArg_Parse")
  EndIf
  
  ProcedureReturn PythonLib
  
EndProcedure


Procedure.s Python_GetProgramFullPath()
  ProcedureReturn PeekS(Pyth_GetProgramFullPath(), -1, #PB_Unicode)
EndProcedure


Procedure.s Python_GetVersion()
  ProcedureReturn PeekS(Pyth_GetVersion(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetPlatform()
  ProcedureReturn PeekS(Pyth_GetPlatform(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetCopyright()
  ProcedureReturn PeekS(Pyth_GetCopyright(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetCompiler()
  ProcedureReturn PeekS(Pyth_GetCompiler(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetBuildInfo()
  ProcedureReturn PeekS(Pyth_GetBuildInfo(), -1, #PB_Ascii)
EndProcedure


Procedure.s Python_GetPythonHome()
  
  Protected Result$, *String
  
  
  *String = Pyth_GetPythonHome()
  If *String
    Result$ = PeekS(*String, -1, #PB_Unicode)
  EndIf
  
  ProcedureReturn Result$
  
EndProcedure


Procedure.s Python_GetPath()
  
  Protected Result$, *String
  
  
  *String = Pyth_GetPath()
  If *String
    Result$ = PeekS(*String, -1, #PB_Unicode)
  EndIf
  
  ProcedureReturn Result$
  
EndProcedure


Procedure.s Python_GetProgramName()
  
  Protected Result$, *String
  
  
  *String = Pyth_GetProgramName()
  If *String
    Result$ = PeekS(*String, -1, #PB_Unicode)
  EndIf
  
  ProcedureReturn Result$
  
EndProcedure


Procedure PythonClose()
  
  If IsLibrary(PythonLib)
    CloseLibrary(PythonLib)
    PythonLib = #Null
  EndIf
  
EndProcedure




CompilerIf #PB_Compiler_IsMainFile
  ;-Demo
  
  Define pystring$, *module, *dictionary, *result, Result.l, ProgramFilename$
  
  OpenConsole()
  
  If PythonInit()
    
    Debug "Version:" + #LF$ + Python_GetVersion() + #LF$
    Debug "Platform:" + #LF$ + Python_GetPlatform() + #LF$
    Debug "Copyright:" + #LF$ + Python_GetCopyright() + #LF$
    Debug "Compiler:" + #LF$ + Python_GetCompiler() + #LF$
    Debug "BuildInfo:" + #LF$ + Python_GetBuildInfo() + #LF$
    
    pystring$ = GetPathPart(ProgramFilename())
    Python_SetPythonHome(@pystring$)
    Debug "PythonHome: " + #LF$ + Python_GetPythonHome() + #LF$
    
    pystring$ = GetPathPart(ProgramFilename()) + "lib\"
    Python_SetPath(@pystring$)
    Debug "PythonPath: " + #LF$ + Python_GetPath() + #LF$
    
    pystring$ = ProgramFilename()
    Python_SetProgramName(@pystring$)
    Debug "ProgramFilename: " + #LF$ + Python_GetProgramName() + #LF$
    Debug "ProgramFullPath: " + #LF$ + Python_GetProgramFullPath() + #LF$
    
    Python_Initialize()
    
    pystring$ = "from time import time, ctime" + #LF$
    pystring$ + "print('Hello PB World from Python!')" + #LF$
    pystring$ + "print('Today is', ctime(time()))"
    
    PythonRun_SimpleString(pystring$)
    
    PythonRun_SimpleString("result = 5 ** 2")
    *module = PythonImport_AddModule("__main__")
    *dictionary = PythonModule_GetDict(*module)
    *result = PythonDict_GetItemString(*dictionary, "result")
    Result = PythonLong_AsLong(*result)
    
    MessageRequester("Python", Str(Result))
    
    Python_Finalize()
    
    PythonClose()
    
  EndIf
  
CompilerEndIf
It is not fully tested, but the example works.
What is really new with 3.5:
You don't need to set environment variables for the PATH stuff.

Btw. the example in the wrapper needs the library stuff below the code in a directory called 'lib'

Code: Select all

pystring$ = GetPathPart(ProgramFilename()) + "lib\"
Python_SetPath(@pystring$)
Bernd

Re: Python 3.5.2 wrapper

Posted: Wed Nov 23, 2016 11:40 am
by Kwai chang caine
Hello INFRATEC :D
It's incredible, all your works are nearly always a thing i need or needed before :shock:
Then very interesting for me 8)

I have try, your code and have error of python with W7 X86 (v5.40 or v5.50) With or without admin rights
At the line 393

Code: Select all

Python_Initialize()
Fatal python error ; Py_Initialize: unable to load the file system codec
ImportError: No module named 'encoding'
And the debugger give me that
Version:
3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)]

Platform:
win32

Copyright:
Copyright (c) 2001-2016 Python Software Foundation.
All Rights Reserved.

Copyright (c) 2000 BeOpen.com.
All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved.

Compiler:
[MSC v.1900 32 bit (Intel)]

BuildInfo:
v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18

PythonHome:
D:\python-3.5.2-embed-win32\

PythonPath:
D:\python-3.5.2-embed-win32\lib\

ProgramFilename:
D:\python-3.5.2-embed-win32\PureBasic_Compilation0.exe

ProgramFullPath:
python

Re: Python 3.5.2 wrapper

Posted: Wed Nov 23, 2016 11:58 am
by infratec
Hi KCC,

you don't read what I write :mrgreen:
Btw. the example in the wrapper needs the library stuff below the code in a directory called 'lib'

Code: Select all

pystring$ = GetPathPart(ProgramFilename()) + "lib\"
Python_SetPath(@pystring$)
So for the example yo need a directory which is called lib directly below the code.
And inside is the complete directorystructure with the pyc files.

Or you have to set the path to the directory where this directory resides.

Bernd

Re: Python 3.5.2 wrapper

Posted: Wed Nov 23, 2016 12:02 pm
by Kwai chang caine
Ohhh !!! excuse me, Yes i have read...but not understand :oops:
The english and me, that do two :oops:
I return to test....i'm very exciting, i love the snakes :D

Re: Python 3.5.2 wrapper

Posted: Wed Nov 23, 2016 12:06 pm
by infratec
If you use

python-3.5.2-embed-win32.zip

the stuff for the lib directory is inside

python35.zip

Unpack this in the directory lib

Bernd

Re: Python 3.5.2 wrapper

Posted: Wed Nov 23, 2016 12:19 pm
by Kwai chang caine
Fortunately, you come a new time for help me, because i was again desesperated :mrgreen:
I have test in all the sens ..and the same problem...so water flow from my eyes :lol:

And this time, i have understand your last help....
And it's miracle !!!! that's works 8)
Image

One thousand of thanks INFRATEC for your patience, and also for all your very interesting and usefull sharing 8)

In fact, i remember now why i wanted used PYTHON before with PB
It's justly always for remote navigator, i search since 10 years a safe solution, and at this moment i found a super lib can using with him : SELENIUM
http://www.purebasic.fr/english/viewtop ... 88#p481288
and
http://www.purebasic.fr/english/viewtop ... 35#p481235

But on this way...i was really alone :lol:

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 12:09 pm
by Kwai chang caine
Is it possible with this code to run a PY file ?

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 12:32 pm
by infratec
With the imported functions?

Yes.

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 12:50 pm
by Kwai chang caine
In fact, i have try during several days to use CURL for send request.
But it's too much hard for me for sending the good request, and after understand the answer, the cookies, and other, other......
So i'm sure, i have not the level to simulate a navigator with CURL :cry:

I have even follow the advice of Normeus and try PhantomJS, but without a very good success :|
Except this style of code, i have not really understand how remote navigator with JS and Phantom :oops:
Examples are not really numerous...

Code: Select all

Script$ = "responsive-screenshot.js https://www.google.fr/ jpg" ; Copie d'ecran JPG en plusieurs definitions ou Pdf
pjs = RunProgram("phantomjs.exe","--ignore-ssl-errors=true " + Script$ + " -v ", "",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Write)
v ", "",#PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Write)
So i continue to search a simple way, for remote a navigator
For the moment, like i have not better, i use MOZREPL pluggin FF with TELNET, and i have some results :D but it's not really the top ..

But they are a some months, someone show me how use SELENIUM with PYTHON

Code: Select all

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox()
browser.get('http://www.google.com')

search = browser.find_element_by_name('q')
search.send_keys("google search through python")
search.send_keys(Keys.RETURN) # hit return after you enter search text
time.sleep(5) # sleep for 5 seconds so you can see the results
browser.quit()
And i remember your splendid works about embeded or Wrapper PYTHON 8)

So like SELENIUM is a headless navigator, it's surely more simple to use it, than manage all the request of server with CURL :idea:
But what i have not really understand it's, is it possible to run a full source like above, or better, in REPL mode ...
In fact..like for CURL, i have several ways, and not understand what is the better for use PYTHON code in PB :oops:

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 1:02 pm
by infratec
Save it as CallPy.pb

Code: Select all

IncludeFile "Python35.pbi"

If OpenConsole()

  If CountProgramParameters() < 2
    PrintN("Usage: call pythonfile funcname [args]")    
    End 1
  EndIf
  
  If PythonInit()
    Python_Initialize()
    
    Debug ProgramParameter(0)
    
    *pName.PythonObject = PythonUnicode_FromString(ProgramParameter(0))
    ; Error checking of pName left out

    *pModule.PythonObject = PythonImport_Import(*pName)
    Python_DECREF(*pName)
    
    Debug ProgramParameter(1)
    
    If *pModule
      *pFunc.PythonObject = PythonObject_GetAttrString(*pModule, ProgramParameter(1))
      ; pFunc is a new reference
      If *pFunc And PythonCallable_Check(*pFunc)
        *pArgs.PythonObject = PythonTuple_New(CountProgramParameters() - 2)
        
        For i = 0 To CountProgramParameters() - 3
          *pValue.PythonObject = PythonLong_FromLong(Val(ProgramParameter(i + 2)))
          If Not *pValue
            Python_DECREF(*pArgs)
            Python_DECREF(*pModule);
            PrintN("Cannot convert argument")
            End 1
          EndIf
          ; pValue reference stolen here:
          PythonTuple_SetItem(*pArgs, i, *pValue)
        Next i
        
        *pValue.PythonObject = PythonObject_CallObject(*pFunc, *pArgs)
        Python_DECREF(*pArgs)
        If *pValue <> #Null
          PrintN("Result of call: " +  Str(PythonLong_AsLong(*pValue)))
          Python_DECREF(*pValue)
        Else
          Python_DECREF(*pFunc)
          Python_DECREF(*pModule)
          PythonErr_Print()
          PrintN("Call failed")
          End 1
        EndIf
        
      Else
        If PythonErr_Occurred()
          PythonErr_Print()
          PrintN("Cannot find function " + ProgramParameter(1))
        EndIf
      EndIf
      
    Else
      PythonErr_Print()
      PrintN("Failed to load " + ProgramParameter(0))
      End 1
    EndIf
       
    Python_Finalize()
  EndIf
  
  Delay(3000)
  
  CloseConsole()
EndIf
Save it as first.py

Code: Select all

def multiply(a,b):
    print("Will compute", a, "times", b)
    c = 0
    for i in range(0, a):
        c = c + b
    return c

#print(multiply1(4,2))
Call it like:

Code: Select all

CallPy first multiply 3 5
Bernd

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 1:17 pm
by Kwai chang caine
Yessss !!! that's works perfectly manually in windows console !!! 8)
After... i have try with PB in ASCII or UNICODE and i have only one letter "R" in return :shock:

Code: Select all

p = RunProgram("D:\Python 3.5.2 wrapper v5.40 [Infratec]\python-3.5.2-embed-win32\CallPy.exe", "first multiply 3 5", "D:\Python 3.5.2 wrapper v5.40 [Infratec]\python-3.5.2-embed-win32", #PB_Program_Open|#PB_Program_Read)
Delay(2000)

While ProgramRunning(p)

 If AvailableProgramOutput(p)
  o$ + ReadProgramString(p) + #CRLF$
  w = ElapsedMilliseconds() + 1000 ; reset timeout
 EndIf
 
 e$ = ReadProgramError(p)
 
 If e$
  o$ + e$ + #CRLF$
  Debug e$
  w = ElapsedMilliseconds() + 1000 ; reset timeout
 EndIf
 
 If w < ElapsedMilliseconds()
  Break
  
 EndIf
 
Wend

Debug o$
 
CloseProgram(p)

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 1:46 pm
by Joris
Hi,

I'm totaly new to wrappers (don't even understand exactly what they just do, so...).
I have some 'basic idea' that wrappers do some translatings...
As I wont to program some little code for my Raspberry Pi I'll need python, yet I don't know much about python either.
So everything that would make it easier to use (learn) would be helpfull.

Can this wrapper make things easier and how then ?
Can I just program in PB and later on use this wrapper to translated into python ?
Sorry for these noob things, I supose it's also quit related to my limited English knowledge.

Thanks.

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 1:53 pm
by infratec
No, it makes nothing easier for you :cry:

A 'wrapper' is a piece of code which allows you to use a foreign dll inside of PB.

In this case it allows you to use the commands which are inside the python35.dll
But this is no help to write something for the Raspberry.

Bernd

Re: Python 3.5.2 wrapper

Posted: Wed Nov 30, 2016 4:26 pm
by Kwai chang caine
I have try to put your code in procedure and never you believe me...that's works :lol:

Code: Select all

IncludeFile "Python35.pbi"
  
Procedure.s Python_Function(PythonFile.s, PythonFunction.s, PythonParameter.s)
 
 CountParameters = CountString(PythonParameter, "|") + 1
 *pName.PythonObject = PythonUnicode_FromString(PythonFile)
 ; Error checking of pName left out
 
 *pModule.PythonObject = PythonImport_Import(*pName)
 Python_DECREF(*pName)

 If *pModule
 
  *pFunc.PythonObject = PythonObject_GetAttrString(*pModule, PythonFunction)
  
  ; pFunc is a new reference
  If *pFunc And PythonCallable_Check(*pFunc)
  
   *pArgs.PythonObject = PythonTuple_New(CountParameters)
   
   For i = 0 To CountParameters - 1
   
    Parameter$ = StringField(PythonParameter, i + 1, "|")
    *pValue.PythonObject = PythonLong_FromLong(Val(Parameter$))
    
    If Not *pValue
     Python_DECREF(*pArgs)
     Python_DECREF(*pModule);
     Answer$ = "Error !! Cannot convert argument"
    EndIf
    
    ; pValue reference stolen here:
    PythonTuple_SetItem(*pArgs, i, *pValue)
    
   Next i
   
   *pValue.PythonObject = PythonObject_CallObject(*pFunc, *pArgs)
   Python_DECREF(*pArgs)
   
   If *pValue <> #Null
    Answer$ = Str(PythonLong_AsLong(*pValue))
    Python_DECREF(*pValue)
   Else
    Python_DECREF(*pFunc)
    Python_DECREF(*pModule)
    PythonErr_Print()
    Answer$ = "Error !! Call failed"
   EndIf
   
  Else
  
   If PythonErr_Occurred()
    PythonErr_Print()
    Answer$ = "Cannot find function " + PythonFunction
   EndIf
   
  EndIf
  
 Else
 
  PythonErr_Print()
  Answer$ = "Error !! Failed to load " + PythonFile
    
 EndIf
 
 ProcedureReturn Answer$
 
EndProcedure

If PythonInit()
 
 Python_Initialize()
 Answer$ = Python_Function("first", "multiply", "3|5")
 
 If Left(Answer$, 5) <> "Error"
  Debug "Result of call: " + Answer$
 Else
  Debug Answer$ 
 EndIf
 
 Python_Finalize()
 
EndIf
 
Now i have try several way but not found how return string value from python

Code: Select all

def multiply(a,b):
    sentence = "Will compute " + str(a) + " times " + str(b)
    c = 0
    for i in range(0, a):
        c = c + b
    return sentence + " = " + str(c)
Obviously this line crash

Code: Select all

 Debug "Result of call: " +  Str(PythonLong_AsLong(*pValue))
They are not PythonLong_AsString() function ? :oops:

Re: Python 3.5.2 wrapper

Posted: Thu Dec 01, 2016 4:19 pm
by Kwai chang caine
I have searching all the day, apparently the funtion "PyString_AsString" exist 8)
http://stackoverflow.com/a/215874

So i have adding

Code: Select all

OSPrototype.l PyString_AsString(*PyObject) 
Global PythonString_AsString.PyString_AsString = GetFunction(PythonLib, "PyString_AsString")
and replace

Code: Select all

 Answer$ = Str(PythonLong_AsLong(*pValue))
to

Code: Select all

Debug PythonString_AsString(*pValue)
But i have a memory error :(