Felip Alàez Nadal | 13 Sep 13:03
Picon

Returning a pike array from C

Hello:

I'm working on implementing the inverse of a matrix and the resolution of linear equations systems into the main pike distribution. Actually, I've finished implementing the LU decomposition of a matrix, which is a preliminar step towards that, as a method for the Math.Matrix class. I've been writing new code at src/modules/Math/matrix_code.h and I've a problem, because the lu method has to return a pike array with 4 elements: 3 Math.Matrix objects which I've created inside the method and an int. Could someone explain me how to create a pike array from the C API and return It? Also, which is the signature which I must declare for pike understanding the method?

I have some other doubts about the C API, but at the moment this is the most important.

Thanks you.
--
Felip Alàez Nadal
Martin Stjernholm | 13 Sep 15:22
Picon
Picon
Picon

Re: Returning a pike array from C

"Felip Alàez Nadal" <uu.nix.uu <at> gmail.com> wrote:

> /.../ I've a problem, because the lu method has to return a pike
> array with 4 elements: 3 Math.Matrix objects which I've created
> inside the method and an int. Could someone explain me how to create
> a pike array from the C API and return It?

Easiest is to use the svalue stack; there are numerous examples
throughout the C sources. It goes something like this:

  push_object (matrix_obj_1);
  push_object (matrix_obj_2);
  push_object (matrix_obj_3);
  push_int (the_integer);
  f_aggregate (4); /* Make an array of the 4 top elements on the stack. */

The array is left on the top of the stack and will become the return
value if you return afterwards.

Note that it's vital to keep track of the ref counts in cases like
this (actually, always when pike objects are handled in C). Depending
on your situation, you should use either push_object (which doesn't
add a ref to the object) or ref_push_object (which does).

Normally when preparing return values, the non-"ref_" variety is
better since you don't want to keep the object after the return. Thus
you can let the stack "take over" the ref you got somewhere else
(typically in a local variable).

If you make too few refs, you'll get a fatal error or segfault pretty
soon (the error will typically be more obvious if you have a pike
compiled with the --with-rtldebug configure option).

If you make too many refs you'll get permanent garbage instead, which
is more difficult to spot. To avoid that I recommend you use the
--with-cleanup-on-exit configure option that'll give you a leak report
on exit.

> Also, which is the signature which I must declare for pike
> understanding the method?

Well, the pike type is array(Math.Matrix|int), of course. Fixing the
corresponding C code for that is handled for you if you're writing a
.cmod. Aren't you?

Felip Alàez Nadal | 13 Sep 16:22
Picon

Re: Returning a pike array from C



Well, the pike type is array(Math.Matrix|int), of course. Fixing the
corresponding C code for that is handled for you if you're writing a
.cmod. Aren't you?

I'm adding code to matrix_code.h, which is written in pure C.

--
Felip Alàez Nadal
Martin Stjernholm | 13 Sep 17:40
Picon
Picon
Picon

Re: Returning a pike array from C

"Felip Alàez Nadal" <uu.nix.uu <at> gmail.com> wrote:

>>
>> Well, the pike type is array(Math.Matrix|int), of course. Fixing the
>> corresponding C code for that is handled for you if you're writing a
>> .cmod. Aren't you?
>>
>
> I'm adding code to matrix_code.h, which is written in pure C.

I see. Well, the closest C type corresponding to
array(Math.Matrix|int) that you can write without complications is
tArr(tOr(tObj,tInt)).

Complications occur if you try to type the object. As you can see in
matrix_code.h, that's not done anywhere else either. If you want to
remedy that (a welcome improvement, of course) then you need to
allocate the program id numbers statically - see src/program_id.h.


Gmane