Ok,
so here it is a bit more:
Save this file as Python31.pbi
Code: Select all
;
; Python 3.1 for PureBASIC
;
PrototypeC Py_Initialize()
PrototypeC Py_Finalize()
PrototypeC Py_IncRef(*PyObject)
PrototypeC Py_DecRef(*PyObject)
PrototypeC.i PyCallable_Check(*PyObject)
PrototypeC.l PyDict_GetItemString(*PyObject, String.s)
PrototypeC PyErr_Print()
PrototypeC.l PyErr_Occurred()
PrototypeC PyErr_Clear()
PrototypeC.l PyImport_AddModule(String.s)
PrototypeC.l PyImport_Import(*PyObject)
PrototypeC.l PyLong_AsLong(*PyObject)
PrototypeC.l PyLong_FromLong(Value.l)
PrototypeC.l PyModule_GetDict(*PyObject)
PrototypeC.l PyObject_GetAttrString(*PyObject, String.s)
PrototypeC.l PyObject_CallObject(*PyObject1, *pyObject2)
PrototypeC.i PyRun_SimpleString(String.s)
PrototypeC.l PyTuple_New(Len.l)
PrototypeC.i PyTuple_SetItem(*PyObject1, Size.l, *PyObject2)
PrototypeC.l PyUnicode_FromString(String.s)
Global PythonLib.l
Structure _typeobject
*ob_base
*tp_name.s ; For printing, in format "<module>.<name>"
tp_basicsize.i
tp_itemsize.i ; 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.i
; 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.i
tp_frees.i
tp_maxalloc.i
*tp_prev
*tp_next
CompilerEndIf
EndStructure
Structure PythonObject
*_ob_next
*_ob_prev
ob_refcnt.i
*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
Procedure.i PythonInit()
PythonLib = OpenLibrary(#PB_Any, "python31.dll")
If PythonLib
Global Python_Initialize.Py_Initialize = GetFunction(PythonLib, "Py_Initialize")
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")
EndIf
ProcedureReturn PythonLib
EndProcedure
Procedure PythonClose()
If PythonLib
CloseLibrary(PythonLib)
EndIf
EndProcedure
Save this file as callpy.pb
Code: Select all
IncludeFile "Python31.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
CloseConsole()
EndIf
And this 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))
Than you should be able to do
callpy first multiply 2 3
at the console.
This is the example from the python tutorial converted to PureBASIC.
But unfortunately I miss something in the pbi file.
If someone has a solution, tell it.
(Look at the macro Python_DECREF)
Bernd