Is there any example about writing Python extension with FBC?
Is there any example about writing Python extension with FBC?
I wanted to try writing a toy extension for Python in FBC. The point is just to prove it's possible or not. If no one ever think about it then my work will be much more difficult :)
Re: Is there any example about writing Python extension with FBC?
I will try writing a toy PHP extension using FBC, too. I hope I could do it and showcase here. No promise, though.
Re: Is there any example about writing Python extension with FBC?
you can write DLL and call the functions in DLL via, for example, ctypes
Re: Is there any example about writing Python extension with FBC?
I looked into translating the python.h file a few years ago. Has a ton of macros in it that made translation difficult. But someone more patient and experienced than I could no doubt do it. FB could be a great language for making python extensions. Python might be a great scripting language to embed in FB apps also. Whether you're making extensions for python or embedding python in your FB app the API is the same.
Re: Is there any example about writing Python extension with FBC?
Are there such solutions for python 3 already ? Most dlls I saw seem to be python 2.
Re: Is there any example about writing Python extension with FBC?
Of course. Python ships with the DLL by default (it's required for the interpreter to function), and the .h files are an optional install in the standard installer. Both the DLL and the .h files are required to build the python interpreter (well technically the source builds the DLL first, then the interpreter binary). So yes, they are current and widely available.
EDIT. I just looked at my python install on Windows 10. the include directory has 99 files in it. Would be quite a project to get that all converted to FB. Probably not all of those files would be needed to do some things.
I agree the simplest way to use FB code from Python is to make a DLL or shared library and used ctypes to marshal parameters and types, and run the FB code directly. Could wrap the calls in Python code to make it more python friendly, and that would be easier and just as fast as trying to make Python objects from FB code using the API.
EDIT. I just looked at my python install on Windows 10. the include directory has 99 files in it. Would be quite a project to get that all converted to FB. Probably not all of those files would be needed to do some things.
I agree the simplest way to use FB code from Python is to make a DLL or shared library and used ctypes to marshal parameters and types, and run the FB code directly. Could wrap the calls in Python code to make it more python friendly, and that would be easier and just as fast as trying to make Python objects from FB code using the API.
Re: Is there any example about writing Python extension with FBC?
I personally managed to use OpenB3D (that is written in C++, but exports functions in the C calling convention) in Python using a simple header file
https://www.syntaxbomb.com/index.php/topic,8314.0.html
The same approach can be used for a library written in FreeBasic, if the functions are declared as cdecl
https://www.syntaxbomb.com/index.php/topic,8314.0.html
The same approach can be used for a library written in FreeBasic, if the functions are declared as cdecl
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Is there any example about writing Python extension with FBC?
A python DLL wrapper isn't a real python module or extension !
You can use any language that can create C compatble dynamic libs for a python extension or module !
I don't use python but here some code as starting point.
Joshy
file "python.bi"file "MyModule.bas"
You can use any language that can create C compatble dynamic libs for a python extension or module !
I don't use python but here some code as starting point.
Joshy
file "python.bi"
Code: Select all
#pragma once
' NOTE: python is case sensitive and the API interface of v3.x differs a little from v2.x
#define PYTHON_API_VERSION 1013 ' !!! this is defined by python-2.7.13 !!!
#define PYTHON_LIB "python27" ' "python23" should work also
#ifndef NULL
#define NULL cptr(any ptr,0)
#endif
' unsigned 32/64-bit
#ifndef size_t
#define size_t uinteger
#endif
' signed 32/64-bit
type Py_ssize_t as integer
const as Py_ssize_t Py_INVALID_SIZE = -1
#if defined( __FB_64BIT__ ) and (not defined(__FB_WIN32__))
type clong as integer
type culong as uinteger
#else
type clong as long
type culong as ulong
#endif
type _typeobject as any
extern "C" lib PYTHON_LIB
' Nothing is actually declared to be a PyObject, but every pointer to a Python object can be cast to a PyObject*.
' This is inheritance built by hand.
' Similarly every pointer to a variable-size Python object can, in addition, be cast to PyVarObject*.
type PyObject
as Py_ssize_t ob_refcnt
as _typeobject ptr ob_type
end type
type PyVarObject
as Py_ssize_t ptr ob_refcnt
as _typeobject ptr ob_type
as Py_ssize_t ob_size
end type
extern _Py_NoneStruct As PyObject
#define Py_None @_Py_NoneStruct
#define Py_REFCNT(ob) (cptr(PyObject ptr,(ob))->ob_refcnt)
#define Py_TYPE(ob) (cptr(PyObject ptr,(ob))->ob_type)
#define Py_SIZE(ob) (cptr(PyVarObject ptr,(ob))->ob_size)
type PyCFunction as function (self as PyObject ptr, args as PyObject ptr) as PyObject ptr
'Flag passed to newmethodobject
#define METH_OLDARGS &H0000
#define METH_VARARGS &H0001
#define METH_KEYWORDS &H0002
' METH_NOARGS and METH_O must not be combined with the flags above.
#define METH_NOARGS &H0004
#define METH_O &H0008
type PyMethodDef
as const zstring ptr ml_name ' The name of the built-in function/method
as PyCFunction ml_meth ' The C function that implements it
as long ml_flags ' Combination of METH_xxx flags, which mostly describe the args expected by the C func
as const zstring ptr ml_doc ' The __doc__ attribute, or NULL
end type
declare function Py_InitModule4(sName as const zstring ptr, _
methods as PyMethodDef ptr, _
sDoc as const zstring ptr = NULL, _
self as PyObject ptr = NULL , _
apiver as long = PYTHON_API_VERSION) as PyObject ptr
declare function PyArg_ParseTuple(args as PyObject ptr, aFormat as const zstring ptr, ...) as long
' PyInt
declare function PyInt_FromString(as zstring ptr, as zstring ptr ptr, as long) as PyObject ptr
declare function PyInt_FromLong(as clong) as PyObject ptr
declare function PyInt_FromSize_t(as size_t) as PyObject ptr
declare function PyInt_FromSsize_t(as Py_ssize_t) as PyObject ptr
declare function PyInt_AsLong(as PyObject ptr) as clong
declare function PyInt_AsSsize_t(as PyObject ptr) as Py_ssize_t
declare function _PyInt_AsInt(as PyObject ptr) as long
declare function PyInt_AsUnsignedLongMask(as PyObject ptr) as PyObject ptr
' PyLong
declare function PyLong_FromString(as zstring ptr, as zstring ptr ptr, as long) as PyObject ptr
declare function PyLong_FromLong(as clong) as PyObject ptr
declare function PyLong_FromUnsignedLong(as culong) as PyObject ptr
declare function PyLong_FromDouble(as double) as PyObject ptr
declare function PyLong_FromSize_t(as size_t) as PyObject ptr
declare function PyLong_FromSsize_t(as Py_ssize_t) as PyObject ptr
declare function PyLong_AsLong(as PyObject ptr) as clong
declare function PyLong_AsLongAndOverflow(as PyObject ptr, as long ptr) as clong
declare function PyLong_AsUnsignedLong(as PyObject ptr) as culong
declare function PyLong_AsUnsignedLongMask(as PyObject ptr) as culong
declare function PyLong_AsSsize_t(as PyObject ptr) as Py_ssize_t
declare function _PyLong_AsInt(as PyObject ptr) as long
declare function PyLong_GetInfo() as PyObject ptr
' PyFloat
declare function PyFloat_FromDouble(as double) as PyObject ptr
declare function PyFloat_AsDouble(as PyObject ptr) as double
end extern
Code: Select all
' file "MyModule.bas"
' fbc -dll MyModule.bas -x MyModule.pyd
#include "python.bi"
extern "C"
function exportBeep (self as PyObject ptr, args as PyObject ptr) as PyObject ptr
beep
return Py_None ' no return value !
end function
function exportAdd (self as PyObject ptr, args as PyObject ptr) as PyObject ptr
dim as long argA,argB
PyArg_ParseTuple(args,"ii",@argA,@argB)
dim as clong result = argA + argB
return PyInt_FromLong(result)
end function
' allocate one more NULL item the last ! e.g. (0)=beep,(1)=add (2)=NULL
dim shared as PyMethodDef methods(2)
' export the init
sub initMyModule() export
methods(0).ml_name = @"beep"
methods(0).ml_meth = @exportBeep
methods(0).ml_flags = METH_NOARGS
methods(0).ml_doc = @"Test calling beep."
methods(1).ml_name = @"add"
methods(1).ml_meth = @exportAdd
methods(1).ml_flags = METH_VARARGS
methods(1).ml_doc = @"Test of adding int numbers."
' last methods(2) is the NULL terminator
Py_InitModule4("MyModule",@methods(0))
end sub
end extern
Last edited by D.J.Peters on May 22, 2021 22:08, edited 1 time in total.
Re: Is there any example about writing Python extension with FBC?
Sure it is. The only difference is that if you're missing the dll, one would fail at runtime, whereas the C API method would fail at compile time if something was wrong, which might or might not be important.D.J.Peters wrote:A python DLL wrapper isn't a real python module or extension !
Everything in your MyModule example can be done in a pure python file where the methods that you defined in your FB example would be defined in pure python and then use ctypes to call the cdecl non-python functions to do the actual work. The result is the same, and the way you call it from other python code is the same.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Is there any example about writing Python extension with FBC?
wrapping a dll or extend the language isn't the same thing !
For sure my mini example isn't a real language module but it shows how the API interface works with FreeBASIC !
By the way if you are a python expert why do not posted a simple solution for the user Cretin Ho ?
Joshy
For sure my mini example isn't a real language module but it shows how the API interface works with FreeBASIC !
By the way if you are a python expert why do not posted a simple solution for the user Cretin Ho ?
Joshy
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Is there any example about writing Python extension with FBC?
fbc -dll MyModule.bas -x MyModule.pyd
Code: Select all
python.exe -
>>> import MyModule
>>> MyModule.beep()
>>>
Re: Is there any example about writing Python extension with FBC?
I agree it's not the same thing techincally, but it has the same effect in the end for many types of FB DLLs or programs. That's what I meant. And given how easy ctypes makes it to load and use C symbols from DLLS, with a standard FB-generated DLL, I think ctypes might win in a variety of circumstances. I am neither an FB or Python expert, although I've had some experience with both. And I have used the Python API before and it's a bit cumbersome I admit but if you need to wrap some kind of object system, it might be more appropriate than ctypes.
Re: Is there any example about writing Python extension with FBC?
libpruio is a library (hardware driver) written in FreeBASIC and PASM assembler code. Beside FB it also ships with bindings/examples for C and Python. The Python CTypes binding gets auto-created by an fbdoc plugin (external emitter) called py_ctypes from the FBC .bi files. Find details atCretin Ho wrote:I wanted to try writing a toy extension for Python in FBC. The point is just to prove it's possible or not. If no one ever think about it then my work will be much more difficult :)
https://github.com/DTJF/libpruio
Re: Is there any example about writing Python extension with FBC?
I was more thinking about the other way around. Native program with embedded python scripting rather than python mainprogram calling native code in dlls. i used a python26.dll but afaik Python 2.6 is dated (I'm no expert, I only add it when forced)caseih wrote:I agree it's not the same thing techincally, but it has the same effect in the end for many types of FB DLLs or programs. That's what I meant. And given how easy ctypes makes it to load and use C symbols from DLLS, with a standard FB-generated DLL, I think ctypes might win in a variety of circumstances. I am neither an FB or Python expert, although I've had some experience with both. And I have used the Python API before and it's a bit cumbersome I admit but if you need to wrap some kind of object system, it might be more appropriate than ctypes.
Re: Is there any example about writing Python extension with FBC?
Yes for sure if you want to embed python in an FB program you need to use the C API. And if you provide shims between FB objects and Python, you can manipulate your FB objects, variables, call functions, etc, from python scripts in the embedded interpreter. Very similar to embedding Lua, or even Javascript. This is used to good effect in some large programs such as FreeCAD and QGIS. My experience embedding Python in a C app is limited to just one instance and it was pretty simplistic but worked well.