To jest polecenie PDL::APIP, które można uruchomić u dostawcy bezpłatnego hostingu OnWorks przy użyciu jednej z naszych wielu bezpłatnych stacji roboczych online, takich jak Ubuntu Online, Fedora Online, emulator online systemu Windows lub emulator online systemu MAC OS
PROGRAM:
IMIĘ
PDL::API - tworzenie piddle'ów z kodu Perla i C/XS
OPIS
Prosta książka kucharska, jak ręcznie tworzyć piddles. Obejmuje zarówno Perl, jak i C/XS
poziom. Dodatkowo opisuje podstawowe procedury PDL, do których można uzyskać dostęp z innych
moduły. Procedury te zasadniczo definiują interfejs API PDL. Jeśli chcesz uzyskać dostęp do piddles z
C/XS, prawdopodobnie musisz wiedzieć o tych funkcjach.
STRESZCZENIE
użyj PDL;
sub mkmypiddle {
...
}
Tworzenie a siusiać ręcznie od Perl
Czasami chcesz stworzyć kałużę ręcznie z danych binarnych. Można to zrobić na
Poziom Perla. Przykłady w dystrybucji obejmują niektóre procedury IO. Kod
poniższy fragment ilustruje wymagane kroki.
użyj karpia;
sub mkmypiddle {
moja $klasa = przesunięcie;
mój $pdl = $class->new;
$pdl->set_datatype($PDL_B);
moje @dims = (1,3,4);
mój $rozmiar = 1;
dla (@dims) { $rozmiar *= $_ }
$pdl->setdims([@dims]);
mój $dref = $pdl->get_dataref();
# odczytaj dane bezpośrednio z pliku
otwórz mój plik $, '
mój $len = $rozmiar*PDL::Core::howbig($pdl->get_datatype);
rechot „nie udało się odczytać wystarczającej ilości danych” if
read( $plik, $$dref, $len) != $len;
zamknij $plik;
$pdl->upd_data();
zwróć $pdl;
}
Tworzenie a siusiać in C
Poniższy przykład tworzy piddle na poziomie C. Korzystamy z modułu „Inline”, który
jest obecnie naprawdę sposobem na łączenie Perla i C. Zwróć uwagę na użycie „PDL_INCLUDE”,
Funkcje „PDL_TYPEMAP”, „PDL_AUTO_INCLUDE” i „PDL_BOOT”, które zostały zaimportowane z
„PDL::Core::Dev”. Aby to zapewnić, są one używane w połączeniu z wywołaniem Inline Config
mapa typów PDL, pliki dołączane PDL i procedury PDL Core znajdują się podczas
kompilacja i późniejsze wykonanie w czasie wykonywania.
użyj PDL::LiteF;
użyj PDL::Core::Dev;
$a = myfloatseq(); # ćwicz nasz konstruktor piddle w C
wydrukuj $a->informacje,”\n”;
# powód tego wywołania konfiguracji wyjaśniono poniżej
użyj Inline C => Konfiguracja =>
INC => &PDL_INCLUDE, # upewnij się, że znajdziemy plik pdlcore.h itd
TYPEMAPS => &PDL_TYPEMAP, # użyj mapy typów PDL
AUTO_INCLUDE => &PDL_AUTO_INCLUDE, # deklaracje globalne i zawiera
BOOT => &PDL_BOOT; # kod rozruchowy, aby załadować strukturę Core
użyj Inline C;
Inline->init; # przydatne, jeśli chcesz móc załadować ten skrypt
__DANE__
__C__
statyczny pdl* new_pdl(int typ danych, PDL_Indx dims[], int ndims)
{
pdl *p = PDL->pdlnew();
PDL->setdims (p, dims, ndims); /* ustaw przyciemnienie */
p->typ danych = typ danych; /* i typ danych */
PDL->allocdata (p); /* przydziel porcję danych */
zwróć p;
}
pdl* myfloatseq()
{
PDL_Indx dims[] = {5,5,5};
pdl *p = nowy_pdl(PDL_F,dims,3);
PDL_Float *dataf = (PDL_Float *) p->dane;
PDL_Indx i; /* wymiary mogą wynosić 64 bity */
dla (i=0;i<5*5*5;i++)
danef[i] = i; /* dane muszą zostać zainicjowane! */
zwróć p;
}
Opakowanie Twój własny dane najnowszych a siusiać
Czasami uzyskujesz fragment danych z innego źródła, na przykład w wyniku przetwarzania obrazu
biblioteka itp. W takim przypadku jedyne, co chcesz zrobić, to zawinąć dane w strukturę piddle w
poziom C. Przykłady wykorzystania tego podejścia można znaleźć w modułach IO (gdzie FastRaw
i FlexRaw używają go do dostępu mmapowanego) oraz moduł Gimp Perl (który używa go do zawijania Gimp
obszary pikseli w piddle). Poniższy skrypt demonstruje prosty przykład:
użyj PDL::LiteF;
użyj PDL::Core::Dev;
użyj PDL::Graphics::PGPLOT;
$b = mkpiddle();
drukuj $b->informacje,"\n";
obrazek1 $b;
użyj Inline C => Konfiguracja =>
INC => &PDL_INCLUDE,
TYPEMAPS => &PDL_TYPEMAP,
AUTO_INCLUDE => &PDL_AUTO_INCLUDE,
BOOT => &PDL_BOOT;
użyj Inline C;
Inline->init;
__DANE__
__C__
/* zawiń dostarczony przez użytkownika fragment danych w piddle
* Musisz określić wymiary (przyciemnienia, przyciemnienia) i
* typ danych (deklarowane są stałe dla typów danych
* w pdl.h; np. PDL_B dla typu bajtu itp.)
*
* gdy utworzony piddle „npdl” zostanie zniszczony na
* Po stronie Perla funkcja przekazana jako „delete_magic”
* parametr zostanie wywołany ze wskaźnikiem do struktury pdl
* i argument „delparam”.
* Daje to możliwość przeprowadzenia dowolnego czyszczenia
* to konieczne. Na przykład być może będziesz musiał
* jawnie wywołaj funkcję, aby zwolnić zasoby
* powiązany ze wskaźnikiem danych.
* Przynajmniej „delete_magic” powinno wyzerować wskaźnik danych piddle'a:
*
* void usuń_mydata(pdl* pdl, int param)
* {
* pdl->dane = 0;
*}
* pdl *p = pdl_wrap(mydata, PDL_B, dims, ndims, Delete_mydata,0);
*
* pdl_wrap zwraca wskaźnik do pdl
* który powstał.
*/
typedef void (*DelMagic)(pdl *, int param);
static void default_magic(pdl *p, int pa) { p->data = 0; }
statyczny pdl* pdl_wrap(void *dane, int typ danych, PDL_Indx dims[],
int ndims, DelMagic usuń_magic, int delparam)
{
pdl* npdl = PDL->pdlnew(); /* pobierz pusty kontener */
PDL->setdims(npdl,dims,ndims); /* ustaw przyciemnienie */
npdl->typ danych = typ danych; /* i typ danych */
npdl->dane = dane; /* wskaż swoje dane */
/* upewnij się, że rdzeń nie ingeruje w twoje dane */
npdl->stan |= PDL_DONTTOUCHDATA | PDL_ALLOCATED;
if (delete_magic != NULL)
PDL->add_deletedata_magic(npdl, usuń_magic, delparam);
więcej
PDL->add_deletedata_magic(npdl, default_magic, 0);
zwróć npdl;
}
#zdefiniuj SZ 256
/* naprawdę głupia funkcja, która tworzy obraz rampy
* w rzeczywistości może to być funkcja nieprzezroczysta
* w jakiejś bibliotece, której używasz
*/
statyczny PDL_Byte* mkramp(void)
{
PDL_Bajt *dane;
int i; /* powinien używać PDL_Indx do obsługi 64-bitowego indeksowania pdl */
if ((dane = malloc(SZ*SZ*sizeof(PDL_Byte))) == NULL)
croak("mkramp: Nie można przydzielić pamięci");
dla (i=0;tj
dane[i] = i % SZ;
dane zwrotne;
}
/* ta funkcja zajmuje się wymaganym porządkiem */
statyczna nieważność usuń_myramp(pdl* p, int param)
{
jeśli (p->dane)
wolne(p->dane);
p->dane = 0;
}
pdl* mkpiddle()
{
PDL_Indx dims[] = {SZ,SZ};
pdl *p;
p = pdl_wrap((void *) mkramp(), PDL_B, przyciemnia, 2,
usuń_myramp,0); /* parametr delparam jest bitralnie ustawiony na 0 */
zwróć p;
}
Kurs krwawy detale
Kurs rdzeń struct -- miejsce at PDL core rutyny at Czas
PDL wykorzystuje technikę podobną do tej stosowanej przez moduły Tk, aby umożliwić korzystanie z innych modułów
jego podstawowe procedury. Wskaźnik do wszystkich współdzielonych podstawowych procedur PDL jest przechowywany w pliku $PDL::SHARE
zmienny. Kod XS powinien przechwycić ten wskaźnik w czasie uruchamiania, aby reszta pliku
Kod C/XS może następnie użyć tego wskaźnika w celu uzyskania dostępu w czasie wykonywania. To początkowe ładowanie
wskaźnik najłatwiej osiągnąć za pomocą funkcji „PDL_AUTO_INCLUDE” i „PDL_BOOT”, które
są definiowane i eksportowane przez „PDL::Core::Dev”. Typowe użycie modułu Inline ma
zostało już zademonstrowane:
użyj Inline C => Konfiguracja =>
INC => &PDL_INCLUDE,
TYPEMAPS => &PDL_TYPEMAP,
AUTO_INCLUDE => &PDL_AUTO_INCLUDE, # deklaracje
BOOT => &PDL_BOOT; # kod sekcji rozruchowej XS
Kod zwrócony przez „PDL_AUTO_INCLUDE” to gwarantuje pdlcore.h jest uwzględniony i deklaruje
zmienne statyczne do przechowywania wskaźnika do struktury „Core”. Wygląda mniej więcej tak
to:
drukuj PDL_AUTO_INCLUDE;
#włączać
statyczny rdzeń* PDL; /* Struktura zawiera podstawowe funkcje C */
statyczny SV* CoreSV; /* Pobiera wskaźnik do Perla var przechowującego podstawową strukturę */
Kod zwrócony przez „PDL_BOOT” pobiera zmienną $PDL::SHARE i inicjuje plik
wskaźnik do struktury „Core”. Dla tych, którzy znają się na API Perla, tutaj jest
kod:
wydrukuj PDL_BOOT;
perl_require_pv („PDL::Core”); /* upewnij się, że PDL::Core jest załadowany */
CoreSV = perl_get_sv("PDL::SHARE",FALSE); /* Wartość SV* */
#ifndef aTHX_
#definiuj THX_
#endif
jeśli (CoreSV==NULL)
Perl_croak(aTHX_ "Potrzebujemy modułu PDL::Core, którego nie znaleziono");
PDL = INT2PTR(Rdzeń*,SvIV(CoreSV)); /* Wartość bazowa */
jeśli (PDL->Wersja != PDL_CORE_VERSION)
Perl_croak(aTHX_ "Należy ponownie skompilować kod z nowo zainstalowanym PDL");
Struktura „Core” zawiera informacje o wersji, aby zapewnić, że struktura zdefiniowana w pdlcore.h
naprawdę odpowiada wartości uzyskanej w czasie wykonywania. Powyższy kod testuje to
jeśli (PDL->Wersja != PDL_CORE_VERSION)
....
Aby uzyskać więcej informacji na temat struktury Core, zobacz PDL::Internals.
Dzięki tym przygotowaniom Twój kod może teraz uzyskać dostęp do podstawowych procedur, jak już pokazano w
niektóre z powyższych przykładów, np
pdl *p = PDL->pdlnew();
Domyślnie zmienna C o nazwie „PDL” służy do przechowywania wskaźnika do struktury „Core”. Jeśli
to jest (z jakiegokolwiek powodu) problem, możesz jawnie określić nazwę dla
zmienna z procedurami „PDL_AUTO_INCLUDE” i „PDL_BOOT”:
użyj Inline C => Konfiguracja =>
INC => &PDL_INCLUDE,
TYPEMAPS => &PDL_TYPEMAP,
AUTO_INCLUDE => &PDL_AUTO_INCLUDE 'PDL_Corep',
BOOT => &PDL_BOOT 'PDL_Corep';
Upewnij się, że używasz tego samego identyfikatora z „PDL_AUTO_INCLUDE” i „PDL_BOOT” i użyj go
ten sam identyfikator we własnym kodzie. Np. kontynuując powyższy przykład:
pdl *p = PDL_Corep->pdlnew();
Trochę wybrany core rutyny wyjaśnione
Pełną definicję struktury „Core” można znaleźć w pliku pdlcore.h, w
Poniżej krótko wyjaśniono najczęściej używane funkcje składowe tej struktury.
· "pdl *SvPDLV(SV *sv)"
· "pdl *SetSV_PDL(SV *sv, pdl *it)"
· "pdl *pdlnew()"
„pdlnew” zwraca pusty obiekt pdl, który wymaga dalszej inicjalizacji, aby go włączyć
w odpowiednią kałużę. Przykład:
pdl *p = PDL->pdlnew();
PDL->setdims(p,dims,ndims);
p->typ danych = PDL_B;
· "pdl *null()"
· "SV *kopia(pdl* p, char* )"
· "void *smalloc(STRLEN nbajtów)"
· „int howbig(int pdl_datatype)”
· "void add_deletedata_magic(pdl *p, void (*func)(pdl*, int), int param)"
· "unieważnij przydzielone dane (pdl *p)"
· "void make_physical(pdl *p)"
· "void make_physdims(pdl *p)"
· "void make_physvaffine(pdl *p)"
· „void qsort_X(PDL_Xtype *data, PDL_Indx a, PDL_Indx b)” i „void
qsort_ind_X(PDL_Xtype *data, PDL_Indx *ix, PDL_Indx a, PDL_Indx b)"
gdzie X jest jednym z B, S, U, L, F, D, a Xtype jest jednym z Byte, Short, Ushort, Long, Float lub
Podwójnie. PDL_Indx jest typem całkowitym C odpowiadającym odpowiedniemu rozmiarowi indeksowania
dla konfiguracji Perla (ivsize i ivtype). Może być „długi” lub „długi”.
long” w zależności od tego, czy Twój Perl jest włączony w wersji 32-bitowej, czy 64-bitowej.
· „float NaN_float” i „double NaN_double”
Są to stałe umożliwiające wygenerowanie wymaganych wartości NaN.
· "void pdl_barf(const char* pat,...)" i "void pdl_warn(const char* pat,...)"
Są to odpowiedniki w kodzie C słów „barf” i „warn”. Obejmują one specjalne obchodzenie się z
komunikaty o błędach lub ostrzeżenia podczas pthreadingu (tj. wielowątkowości procesora).
odłóż wiadomości do czasu zakończenia pthreadingu. Po zakończeniu pthreadingu,
W Perlu wywoływane są komendy „barf” lub „warn” z odroczonymi wiadomościami. Jest to konieczne do utrzymania
przed wywołaniem „barf” lub „warn” Perla podczas pthreadingu, co może powodować błędy seg.
Należy zauważyć, że „barf” i „warn” zostały na nowo zdefiniowane (przy użyciu makr preprocesora c) w
pdlcore.h na „PDL->barf” i „PDL->warn”. Ma to na celu uniknięcie jakiegokolwiek kodu XS lub PP
wywołanie bezpośrednio perla „barf” lub „warn”, co może powodować błędy podczas wykonywania operacji
pwątkowanie.
Zobacz PDL::ParallelCPU, aby uzyskać więcej informacji na temat pthreadingu.
Korzystaj z PDL::APIP online, korzystając z usług onworks.net