Re: Return struct causes segfault
Thor Andreas Tangen <[email protected]> Mon, 30 Sep 2013 08:30:32 +0200
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <CA+wbTUpQxsUcc6R+Synkr_y+rUjJJNYNEn50qTT9X6aMPuFxYw@mail.gmail.com> |
Thats a challenge then, that the size is unknown. I dont have too much experience here, but you could allocate the memory persistently in you C-library using malloc, and in the destructor of the PhotoInfo class in Python, make sure to call some memory free function in you c-library to make sure the memory is freed correctly. You can use vectors to populate your array and then allocat using malloc since you now know the size and copy over the data from the vector to the new memory. Someone else might have a more elegant solution to this, as I said I have not done this type of operation before. Thor Andreas On Mon, Sep 30, 2013 at 8:21 AM, Nicholas Earl <[email protected]> wrote: > I see. So -- sorry to drag you through this -- if I create an instance of > PhotoInfo, which is a subclass of ctypes.STRUCTURE, and then pass that in > as a parameter to the C function, I could then have the C function assign > the array object to the PhotoInfo variables? But the array objects can' t > be pointers, right? The problem is, I don't know how big the array objects > will be, so I've been using vectors and then retrieving their array > pointers. > > Thanks for your help, > > Nicholas Earl > Graduate Research Assistant > San Diego State University > > > On Sun, Sep 29, 2013 at 11:17 PM, Thor Andreas Tangen <[email protected]>wrote: > >> I would allocate the memory on the python side. Allocating persistent >> memory on the C-side makes it difficult to free, unless you do it >> specifically. If you allocate it on the python side the GC would take care >> of all memory management. >> >> Thor Andreas >> >> >> On Mon, Sep 30, 2013 at 8:10 AM, Nicholas Earl <[email protected]>wrote: >> >>> Thor, >>> >>> Thanks for the response! Is there, then, a standard way of calling a C >>> function, creating an object (struct) that can hold two arrays, and then >>> return that data object to the python program? >>> >>> Thanks, >>> >>> Nicholas Earl >>> Graduate Research Assistant >>> San Diego State University >>> >>> >>> On Sun, Sep 29, 2013 at 10:11 PM, Thor Andreas Tangen <[email protected] >>> > wrote: >>> >>>> Hi, >>>> >>>> The vectors times and fluxes are destroyed when exiting the function >>>> start, the memory allocated and pointed to be times and fluxes are invalid >>>> upon exiting the function. >>>> >>>> Thor Andreas >>>> >>>> >>>> On Sun, Sep 29, 2013 at 12:53 AM, Nicholas Earl <[email protected]>wrote: >>>> >>>>> I'm struggling with returning a struct value using ctypes. Mainly, it >>>>> keeps segfaulting when I try and get the values from the returned object. I >>>>> have my python script setup like this: >>>>> >>>>> import ctypes >>>>> import numpy as np >>>>> from numpy.ctypeslib import ndpointer >>>>> >>>>> >>>>> class PhotoInfo(ctypes.Structure): >>>>> _fields_ = [ >>>>> ('times', ctypes.POINTER(ctypes.c_double)), >>>>> ('fluxes', ctypes.POINTER(ctypes.c_double)), >>>>> ] >>>>> >>>>> >>>>> def main(): >>>>> lib = ctypes.cdll.LoadLibrary('cfile.so') >>>>> >>>>> start = lib.start >>>>> start.restype = ctypes.POINTER(PhotoInfo) >>>>> start.argtypes = [ >>>>> ctypes.c_int, >>>>> ndpointer(ctypes.c_double), >>>>> ] >>>>> >>>>> N = 3 >>>>> mass = np.array([0.00020335520, 5.977884E-05, 9.320397E-08]) >>>>> >>>>> phin = start(N, mass) >>>>> >>>>> print phin[0].times[0] >>>>> >>>>> And in my c file: >>>>> >>>>> #include <iostream> >>>>> #include <iomanip> >>>>> #include <fstream> >>>>> #include <sstream> >>>>> #include <string> >>>>> #include <vector> >>>>> #include <math.h> >>>>> #include <stdlib.h> >>>>> #include <stdio.h> >>>>> >>>>> using namespace std; >>>>> >>>>> typedef struct { >>>>> double *times; >>>>> double *fluxes; >>>>> } PhotoInfo; >>>>> >>>>> extern "C" { >>>>> PhotoInfo *start(int N, double *mass); >>>>> } >>>>> >>>>> PhotoInfo *start(int N, double *mass) { >>>>> PhotoInfo phin; >>>>> vector<double> times; >>>>> vector<double> fluxes; >>>>> >>>>> // Here, I read in a file and fill times and fluxes with doubles using >>>>> // times.push_back(t) and fluxes.push_back(f)\ >>>>> >>>>> phin.times = ×[0]; >>>>> phin.fluxes = ×[0]; >>>>> return &phin; >>>>> } >>>>> >>>>> Any guidance on this would be greatly appreciated! >>>>> >>>>> Nicholas Earl >>>>> Graduate Research Assistant >>>>> San Diego State University >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> October Webinars: Code for Performance >>>>> Free Intel webinars can help you accelerate application performance. >>>>> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the >>>>> most from >>>>> the latest Intel processors and coprocessors. See abstracts and >>>>> register > >>>>> >>>>> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk >>>>> _______________________________________________ >>>>> ctypes-users mailing list >>>>> [email protected] >>>>> https://lists.sourceforge.net/lists/listinfo/ctypes-users >>>>> >>>>> >>>> >>> >> > ------------------------------------------------------------------------------ October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register > http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk _______________________________________________ ctypes-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ctypes-users