LINUX.ORG.RU

История изменений

Исправление AITap, (текущая версия) :

Полдня чтения perlxstut, perlxs, perlapi и Google:

1) Создаём скелет модуля: h2xs -Afn My::Module
2) cd My-Module && $EDITOR Module.xs
3) #include<myfile.h>
И пишем обёртку для функции. Например, для «модельного» случая:

typedef struct { int x; int y; } point;
int get_points (point **buf, int cnt);

int get_points (point **buf,int cnt) {
        int i;
        (*buf)=(point *)malloc(sizeof(point)*cnt);
        for (i=0;i<cnt;i++) {
                (*buf)[i]=(point){7,7};
        }
        return cnt;
}
AV *
get_points(int num)
        CODE:  
                // int прозрачно превращается в типы C и обратно
                point* buf; // а массивы придётся превращать руками
                int cnt = get_points(&buf,num);
                // ---
                RETVAL = newAV(); // создаём массив
                sv_2mortal((SV*)RETVAL); // из-за бага в XS возвращаемые массивы нужно дополнительно делать "смертными"
                // ---
                int i;
                for (i=0;i<cnt;i++) {
                        AV* arr = newAV(); // создаём массив. его не нужно делать смертным
                        av_push(arr,newSViv((IV)buf[i].x)); // добавляем в него созданный из int Perl'овый скаляр
                        av_push(arr,newSViv((IV)buf[i].y));
                        SV* ref = newRV_noinc((SV*)arr); // получаем ссылку на этот массив
                        av_push(RETVAL,ref); // и запихиваем её в возвращаемое значение
                }
                free(buf); // не забываем
        OUTPUT:
                RETVAL // Perl возвращает ссылку на массив ссылок на массивы

4) Не забываем включить в Makefile.PL:

        # Un-comment this if you add C files to link with later:
    OBJECT            => '$(O_FILES)', # link all the C files too
5) perl Makefile.PL && make test

 perl -Iblib/arch -Ilib -MAITap::Module -MData::Dumper -e 'print Dumper AITap::Module::get_points(3)'
$VAR1 = [
          [
            7,
            7
          ],
          [
            7,
            7
          ],
          [
            7,
            7
          ]
        ];

// Заранее извиняюсь за мой французский C. Я разговариваю на нём со словарём.

Исходная версия AITap, :

Полдня чтения perlxstut, perlxs, perlapi и Google:

1) Создаём скелет модуля: h2xs -Afn My::Module
2) cd My-Module && $EDITOR Module.xs
3) #include<myfile.h>
И пишем обёртку для функции. Например, для «модельного» случая:

typedef struct { int x; int y; } point;
int get_points (point **buf, int cnt);

int get_points (point **buf,int cnt) {
        int i;
        (*buf)=(point *)malloc(sizeof(point)*cnt);
        for (i=0;i<cnt;i++) {
                (*buf)[i]=(point){7,7};
        }
        return cnt;
}
AV *
get_points(int num)
        CODE:  
                // int прозрачно превращается в типы C и обратно
                point* buf; // а массивы придётся превращать руками
                int cnt = get_points(&buf,num);
                // ---
                RETVAL = newAV(); // создаём массив
                sv_2mortal((SV*)RETVAL); // из-за бага в XS возвращаемые массивы нужно дополнительно делать "смертными"
                // ---
                int i;
                for (i=0;i<cnt;i++) {
                        AV* arr = newAV(); // создаём массив. его не нужно делать смертным
                        av_push(arr,newSViv((IV)buf[i].x)); // добавляем в него созданный из int Perl'овый скаляр
                        av_push(arr,newSViv((IV)buf[i].y));
                        SV* ref = newRV_noinc((SV*)arr); // получаем ссылку на этот массив
                        av_push(RETVAL,ref); // и запихиваем её в возвращаемое значение
                }
                free(buf); // не забываем
        OUTPUT:
                RETVAL // Perl возвращает ссылку на массив ссылок на массивы

4) Не забываем включить в Makefile.PL:

        # Un-comment this if you add C files to link with later:
    OBJECT            => '$(O_FILES)', # link all the C files too
5) perl Makefile.PL && make test

 perl -Iblib/arch -Ilib -MAITap::Module -MData::Dumper -e 'print Dumper AITap::Module::get_points(3)'
$VAR1 = [
          [
            7,
            7
          ],
          [
            7,
            7
          ],
          [
            7,
            7
          ]
        ];