Python 3.5.2 wrapper

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

Python 3.5.2 wrapper

Post 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
Last edited by infratec on Fri Dec 02, 2016 7:50 pm, edited 1 time in total.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post 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
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Python 3.5.2 wrapper

Post 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
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post 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
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Python 3.5.2 wrapper

Post 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
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post 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:
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post by Kwai chang caine »

Is it possible with this code to run a PY file ?
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Python 3.5.2 wrapper

Post by infratec »

With the imported functions?

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

Re: Python 3.5.2 wrapper

Post 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:
Last edited by Kwai chang caine on Wed Nov 30, 2016 1:02 pm, edited 1 time in total.
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Python 3.5.2 wrapper

Post 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
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post 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)
ImageThe happiness is a road...
Not a destination
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Python 3.5.2 wrapper

Post 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.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Python 3.5.2 wrapper

Post 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
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post 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:
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5357
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Python 3.5.2 wrapper

Post 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 :(
ImageThe happiness is a road...
Not a destination
Post Reply