
Hi Armin/Maciej, Thanks for the reply, following the code sample I wrote up the following: from cffi import FFI ffi = FFI() ffi.set_source("_ical_cffi_ext", """ // passed to the real C compiler #include <libical/ical.h> """, include_dirs=['./include'], # where ical.h is libraries=['ical'], library_dirs=['./lib'],) # or a list of libraries to link with ffi.cdef(""" // some declarations from the man page typedef struct icalcomponent_impl icalcomponent; typedef struct icalproperty_impl icalproperty; typedef ... icalparameter; typedef struct icalvalue_impl icalvalue; typedef ... icaltimezonechange; //really typedef struct _icaltimezonechange icaltimezonechange; struct _icaltimezonechange { int utc_offset; int prev_utc_offset; int year; /**< Actual year, e.g. 2001. */ int month; /**< 1 (Jan) to 12 (Dec). */ int day; int hour; int minute; int second; int is_daylight; }; """) if __name__ == "__main__": ffi.compile() _icaltimezonechange is opaque as its in src/libical/icaltimezone.c a c file and not in in ical.h. However this struct is required for my purpose. However when it compiles I do get errors like: _ical_cffi_ext.c:455: error: dereferencing pointer to incomplete type _ical_cffi_ext.c:457: error: invalid use of undefined type 'struct _icaltimezonechange' _ical_cffi_ext.c:458: error: dereferencing pointer to incomplete type _ical_cffi_ext.c:468: error: invalid application of 'sizeof' to incomplete type 'struct _icaltimezonechange' _ical_cffi_ext.c:468: error: initializer element is not constant _ical_cffi_ext.c:468: error: (near initialization for '_cffi_struct_unions[2].alignment') Can I know what should be done for these cases? Thanks, -Roshan On Tue, Sep 15, 2015 at 8:17 AM, Armin Rigo <arigo@tunes.org> wrote:

Hi Roshan, On Fri, Sep 18, 2015 at 10:02 AM, Roshan Cherian <cherian.rosh@gmail.com> wrote:
_icaltimezonechange is opaque as its in src/libical/icaltimezone.c a c file and not in in ical.h. However this struct is required for my purpose.
All structs must be declared in C before you import them into Python. In this case, the "cheat" to access this structure is the same as if you wrote C code: you need to give the real C compiler a declaration of this struct. Then you can import it as you did. (So you need to write this struct twice.) ffi.set_source("_ical_cffi_ext", """ // passed to the real C compiler #include <libical/ical.h> struct _icaltimezonechange { int utc_offset; int prev_utc_offset; int year; /**< Actual year, e.g. 2001. */ int month; /**< 1 (Jan) to 12 (Dec). */ int day; int hour; int minute; int second; int is_daylight; }; """, include_dirs=['./include'], # where ical.h is libraries=['ical'], library_dirs=['./lib'],) # or a list of libraries to link with A bientôt, Armin.

Thanks Armin and Maciej. I now have the code running on a box without gcc on it and I don't use ffi.dlopen, I now distribute the generated _ical_cffi_ext.c which was generated using ffi.compile() and use distuitils to build it to site-packges of pypy. Thanks a lot for this. I do have a question on memory management, currently I am using lib. Currently lib provides me with icalcomponent_free which I pass in as the function to be used in __del__. Should I be using this or should I be using something specific from the python extension? This is what I see in the python extension which was created. static void _cffi_d_icalcomponent_free(icalcomponent * x0) { icalcomponent_free(x0); } #ifndef PYPY_VERSION static PyObject * _cffi_f_icalcomponent_free(PyObject *self, PyObject *arg0) { icalcomponent * x0; Py_ssize_t datasize; datasize = _cffi_prepare_pointer_call_argument( _cffi_type(1), arg0, (char **)&x0); if (datasize != 0) { if (datasize < 0) return NULL; x0 = (icalcomponent *)alloca((size_t)datasize); memset((void *)x0, 0, (size_t)datasize); if (_cffi_convert_array_from_object((char *)x0, _cffi_type(1), arg0) < 0) return NULL; } Py_BEGIN_ALLOW_THREADS _cffi_restore_errno(); { icalcomponent_free(x0); } _cffi_save_errno(); Py_END_ALLOW_THREADS (void)self; /* unused */ Py_INCREF(Py_None); return Py_None; } #else # define _cffi_f_icalcomponent_free _cffi_d_icalcomponent_free #endif Thanks for the help, -Roshan On Fri, Sep 18, 2015 at 3:49 AM, Armin Rigo <arigo@tunes.org> wrote:

Hi Roshan, On Mon, Sep 21, 2015 at 9:58 PM, Roshan Cherian <cherian.rosh@gmail.com> wrote:
This is the code in C that implements the function "lib.icalcomponent_free()". There are similar pieces of code for all other functions. What are you asking specifically? If it's ok to call such functions from a __del__()? Yes, it is. Sometimes you can use ffi.gc() instead and give the function "lib.icalcomponent_free" directly as a second argument; then you don't need a __del__. But if the __del__ solution suits your case, then that's fine. A bientôt, Armin.

Hi Roshan, On Fri, Sep 18, 2015 at 10:02 AM, Roshan Cherian <cherian.rosh@gmail.com> wrote:
_icaltimezonechange is opaque as its in src/libical/icaltimezone.c a c file and not in in ical.h. However this struct is required for my purpose.
All structs must be declared in C before you import them into Python. In this case, the "cheat" to access this structure is the same as if you wrote C code: you need to give the real C compiler a declaration of this struct. Then you can import it as you did. (So you need to write this struct twice.) ffi.set_source("_ical_cffi_ext", """ // passed to the real C compiler #include <libical/ical.h> struct _icaltimezonechange { int utc_offset; int prev_utc_offset; int year; /**< Actual year, e.g. 2001. */ int month; /**< 1 (Jan) to 12 (Dec). */ int day; int hour; int minute; int second; int is_daylight; }; """, include_dirs=['./include'], # where ical.h is libraries=['ical'], library_dirs=['./lib'],) # or a list of libraries to link with A bientôt, Armin.

Thanks Armin and Maciej. I now have the code running on a box without gcc on it and I don't use ffi.dlopen, I now distribute the generated _ical_cffi_ext.c which was generated using ffi.compile() and use distuitils to build it to site-packges of pypy. Thanks a lot for this. I do have a question on memory management, currently I am using lib. Currently lib provides me with icalcomponent_free which I pass in as the function to be used in __del__. Should I be using this or should I be using something specific from the python extension? This is what I see in the python extension which was created. static void _cffi_d_icalcomponent_free(icalcomponent * x0) { icalcomponent_free(x0); } #ifndef PYPY_VERSION static PyObject * _cffi_f_icalcomponent_free(PyObject *self, PyObject *arg0) { icalcomponent * x0; Py_ssize_t datasize; datasize = _cffi_prepare_pointer_call_argument( _cffi_type(1), arg0, (char **)&x0); if (datasize != 0) { if (datasize < 0) return NULL; x0 = (icalcomponent *)alloca((size_t)datasize); memset((void *)x0, 0, (size_t)datasize); if (_cffi_convert_array_from_object((char *)x0, _cffi_type(1), arg0) < 0) return NULL; } Py_BEGIN_ALLOW_THREADS _cffi_restore_errno(); { icalcomponent_free(x0); } _cffi_save_errno(); Py_END_ALLOW_THREADS (void)self; /* unused */ Py_INCREF(Py_None); return Py_None; } #else # define _cffi_f_icalcomponent_free _cffi_d_icalcomponent_free #endif Thanks for the help, -Roshan On Fri, Sep 18, 2015 at 3:49 AM, Armin Rigo <arigo@tunes.org> wrote:

Hi Roshan, On Mon, Sep 21, 2015 at 9:58 PM, Roshan Cherian <cherian.rosh@gmail.com> wrote:
This is the code in C that implements the function "lib.icalcomponent_free()". There are similar pieces of code for all other functions. What are you asking specifically? If it's ok to call such functions from a __del__()? Yes, it is. Sometimes you can use ffi.gc() instead and give the function "lib.icalcomponent_free" directly as a second argument; then you don't need a __del__. But if the __del__ solution suits your case, then that's fine. A bientôt, Armin.
participants (2)
-
Armin Rigo
-
Roshan Cherian