İngilizceFransızcaİspanyolca

OnWorks favicon'u

rxgen - Bulutta Çevrimiçi

Ubuntu Online, Fedora Online, Windows çevrimiçi emülatörü veya MAC OS çevrimiçi emülatörü üzerinden OnWorks ücretsiz barındırma sağlayıcısında rxgen çalıştırın

Bu, Ubuntu Online, Fedora Online, Windows çevrimiçi emülatörü veya MAC OS çevrimiçi emülatörü gibi birden fazla ücretsiz çevrimiçi iş istasyonumuzdan birini kullanarak OnWorks ücretsiz barındırma sağlayıcısında çalıştırılabilen rxgen komutudur.

Program:

ADI


rxgen - Rx uzaktan prosedür çağrı paketi için saplama oluşturucu

SİNOPSİS


rxgen [-h | -c | -C | -S | -r] [-dkpR]
[-I dir] [-P önek] [-o dış dosya] [dosyada]

rxgen -s taşıma [-o dış dosya] [dosyada]

rxgen -l [-o dış dosya] [dosyada]

rxgen -m [-o dış dosya] [dosyada]

TANIM


rxgen Rx RPC protokolünü uygulamak için C kodu üreten bir araçtır; girdi olarak alır
C'ye benzer bir uygulama arayüzünün tanımı ve bir dizi sunucu üretir
ve/veya istemci saplama rutinleri, RPC tabanlı programlara bağlanacak. Bu saplamalar izin verir
yerel prosedür çağrıları yoluyla uzak prosedürleri çağırmak için programlar. rxgen bir uzantıdır
Sun'ın rpcgen (sürüm 3.9) ve dolu tutar rpcgen işlevsellik (en azından
sürüm). Bakınız rpcgen(1) Sun'ın RPC'ye özel bayrakları hakkında daha fazla ayrıntı için ve
faydalı örneklerle birlikte RPC diline ilişkin RPC programlama kılavuzuna bakın.

SEÇENEKLER


rxgen birkaç farklı modda çalışır. Oluşturulan çıktı dosyaları üretilebilir
ayrı ayrı (birini kullanarak -h, -c, -Cya da -S) veya toplu olarak. Tüm çıktı dosyaları
varsayılan kullanıldığında (yani, seçenek yokken) oluşturulur veya çıktı,
sunucu taslakları (-C ve -S) ne zaman -r bayrak kullanılır. Aşağıdaki türleri açıklar
oluşturulan çıktı dosyaları (basitlik için, Dosya ana çıktı dosya adına atıfta bulunur):

-h Standart RPCL tanımlarından C veri tanımları (bir başlık dosyası) oluşturun (varsayılan
uzantı: Dosya.H).

-c RPCL tarafından açıklanan protokolü seri hale getirmek için gereken XDR rutinlerini derleyin.
Tüm bildirimler için XDR rutinleri oluşturun (varsayılan uzantı: Dosya.xdr.c).

-C Tüm istemci tarafı saplama rutinlerini oluşturun (varsayılan uzantı: Dosya.cs.c).
Bu dosyada bir rutin çağırmak, argümanların paketlenmesine ve aracılığıyla gönderilmesine neden olur.
Rx (veya R).

-S Tüm sunucu tarafı saplama rutinlerini oluşturun (varsayılan uzantı: Dosya.ss.c).
Argümanlar paketten çıkarılır ve karşılık gelen sunucu rutini çağrılır.

-r tarafından üretilen iki varsayılan uzantı dosyasını oluşturun. -C ve -S seçenekleri.

Aşağıdaki seçenekler herhangi bir kombinasyonda kullanılabilir: rxgen aramalar:

-R Varsayılan olan Rx'in aksine, eski \R protokolü için kod oluşturun.

-k Oluşturulan kodun çekirdek tarafından kullanılması amaçlandığında belirtilmelidir;
hedef çıktı için olduğunda özel "içerir" ve diğer özellikler üretilir
çekirdek.

-p Paket kombinasyon işareti: birden fazla paket tek bir pakete dahil edildiğinde
belirtim dosyasında, hepsi için tek bir Yürütme İsteği rutini kullanılacaktır.
bu bayrağın sonucu. Varsayılan, aşağıdakiler için bireysel Yürütme İsteği taslakları oluşturmaktır.
her paket.

-I dir
Benzer -I C derleyicisindeki bayrak (cc). Bu bayrak ön-
işlemci (cpp) böylece bu dizin dir için standart arama listesinden önce aranır
#include dosyaları. Beklendiği gibi, çoklu -I bayraklar aynı anda kullanılabilir.

-P önek
The önek bu anahtarı izleyen dize, oluşturulan tüm çıktı dosyalarının başına eklenir;
birden çok çalıştırma aynı arabirimin farklı sürümlerini üretmek istediğinde kullanışlıdır
(örneğin, çekirdek ve çekirdek olmayan sürümler).

-d Hata ayıklama modu; sadece gerektiğinde rxgen hata ayıklanacak (örneğin, aracılığıyla dbx).

-o dış dosya
Çıktı dosyasının adını belirtin. Hiçbiri belirtilmemişse, standart çıktı
kullanılmış (-c, -h, -C, ve -S yalnızca modlar). Bir çıktı dosyası bir
çok çıktılı dosya seçeneği (varsayılan gibi veya seçenekli -r), sonra dış dosya
varsayılan olarak oluşturulan adın yerini alır (yapılandırmanın ana
dosya adı).

The -s, -l, ve -m seçenekler sadece için mevcuttur rpcgen destek. Görmek rpcgen(1) için
kullanımları hakkında bilgi.

rxgen SÖZDİZİMİ ÖZET


Şartname dosyası:

|
|
|
|
|


:

"paket"

:

"önek"

:

"başlangıç ​​kodu"

:

"bölünmüş ön ek" ";"

:

"IN =" "|"
"ÇIKIŞ =" "|"


:

["proc"] [ ] [ ]
["bölünmüş" | "çok"]
["=" ] ";"

:

"(" ")"

:


["<" ">" | "[" "]"] | BOŞ

:

"," | BOŞ

:

"GİRİŞ" | "ÇIKIŞ" | "ÇIKIŞ" | BOŞ

:

| BOŞ

:
:
:
:
:
:
:
:
:



:
:

Sun'ın RPCL dil sözdizimi (bkz. rpcgen(1))

rxgen KOMUTLAR


Yorumlar ve Ön İşleme
Giriş arayüzü, C'den geçirilen önişlemci direktiflerini içerebilir.
önişlemci (yani "cpp"). Önişlemci tüm girdi dosyaları üzerinde çalışmadan önce çalıştığı için
aslında tarafından yorumlandı rxgen, herşey cpp yönergeler (#include, #ifdefs, #defines, vb.)
yasal ve memnuniyetle karşılandı rxgen giriş dosyası. Tabii ki, bu önişlemcilerin hiçbiri
direktifler oluşturulan dosyalardan herhangi birine dahil edilecektir. Ayrımları kolaylaştırmak için
farklı çıktı dosyaları türleri arasında, rxgen belirli özel tanımlar cpp için semboller
tarafından kullanmak rxgen programcı. Bunlar RPC_HDR'dir (başlığa derlenirken tanımlanır,
Dosya.h, dosyalar), RPC_XDR (xdr'da derlenirken tanımlanır, Dosya.xdr.c, dosyalar),
RPC_CLIENT (istemci taslaklarında derlenirken tanımlanır, Dosya.cs.c, dosyalar) ve
RPC_SERVER (sunucu taslaklarına derlenirken tanımlanır, Dosya.ss.c, dosyalar).

Ek olarak, rxgen kendi başına küçük bir ön işleme yapar. "%" ile başlayan herhangi bir satır
tarafından yorumlanmadan doğrudan çıktı dosyasına iletilir. rxgen. Daha ağır bir kitle için
yorumlanmamış kodun boşaltılması, bu tür tüm kodların bir
"#include" dosyasını seçin ve önüne "%" koyarak geçirin. Giriş arayüzü ayrıca herhangi bir
Elbette görmezden gelinen C tarzı yorumlar. Yorumlama belirteç tabanlıdır, bu nedenle
ayrı ifadelerin özel satır yönlendirmesi gerekli değildir. rxgen Ayrıca sağlar
oldukça zengin ve yararlı bir dizi hata raporu, bunları kesin hat konumuna göre tanımlıyor ve
hata türü. Ayrıca, rxgen standart içerme için otomatik olarak #include satırları oluşturur
gibi dosyalar rx/xdr.h ve rx/rx.h, bundan oluşturulan başlık dosyasıyla birlikte
Arayüz aynı

ön ek saplama prosedürler
The paket ifade söyler rxgen arayüz paketinin adı. İçin kullanılır
oluşturulan tüm saplama rutinlerinin adlarının önüne ekleme ve istek prosedürünü yürütme.
Örneğin:

paket AFS_

yürütme isteği prosedürünün AFS_ExecuteRequest olarak adlandırılmasına neden olur (Uyarı:
sürüm ExecuteRequest adına paket adından sonra ek bir "_" eklendi;
bu nedenle, bir ExecuteRequest arabirim rutinine ve belirli bir saplamaya sahip olmadığınızdan emin olun.
Rutin, Getir deyin, aslında AFS_Fetch olarak adlandırılacak. Çoklu paket ifadeleri (geçerli
maksimum boyut 10'dur) yapılandırma başına izin verilir ve birden çok
arayüzler uygulanır (sondaki örneğe bakın). Bu gibi durumlarda, şunu unutmayın:
the -p bayrak, yalnızca bir ExecuteRequest prosedürünün oluşturulmasıyla sonuçlanır.
birden çok arabirimi tanır ve adının önüne ilk paket eklenir
Beyan. Varsayılan durumda, aşağıdakiler için bağımsız ExecuteRequest prosedürleri oluşturulacaktır.
her paketlenmiş uzaktan prosedür çağrıları grubu.

The önek deyimi, içindeki uzak yordam adlarına yapılan tüm çağrıların başına eklenecek bir ad sağlar.
ExecuteRequest saplama rutini. Sunucu diğerlerine RPC çağrıları yaptığında kullanışlıdır.
sunucular (örneğin, hata ayıklama amacıyla). Örneğin:

S öneki

sunucudan çağrılan tüm rutinlerin adının başına "S" adının eklenmesine neden olur
taslaklar. Sunucu daha sonra orijinal adı arayabilir ve istemci taslaklarını alabilir.

rxgen prosedür beyanname
The proc ifadesi en yaygın (ve anlamlı) olanıdır. rxgen arayüz. sözdizimi
açıklama:

[proc] [ ] [ ] ( , ..., )
[böl | çoklu] [= ] ;

nerede:

· "proc", prosedür ifadesinin isteğe bağlı bir önekidir. Bu sadece stilistik bir öğe
ve gerekli bir prosedür sınırlayıcı değil.

· prosedürün adıdır. Prosedürün adının bile
isteğe bağlı. Bu, yalnızca verilen prosedürün adı ile aynı olduğunda anlamlıdır.
sonuncunun adı paket beyanı (yani, "RCallBack paketi" ve beyanı
"RCallBack" prosedürü).

· , varsa, ExecuteRequest prosedürünün bunun yerine bu saplamayı çağırmasına neden olur
Bu işlem koduna sahip bir aramanın kodu çözüldüğünde otomatik olarak oluşturulan saplamanın.

· bu prosedürün işlem kodu olan bir sabit veya semboldür. Biri kullanabilir
önişlemci özellikleri (yani, #define), const RPC dili özelliği veya eski
işlem kodları olarak iyi sabitler. İşlem kodlarının bazı ek değerlendirmeleri/işlenmesi yapılır.
Özellikle, mükerrer ve var olmayan işlem kodlarının kontrolleri yapılır.
işlem kodu dizilerindeki "delikleri" (yani ardışık işlem kodlarındaki boşlukları) kontrol eder. İçin
örneğin, işlem kodlarında "delikler" olduğunda, ExecuteRequest'in
prosedürü kullanır dava daha hızlı (ve daha küçük, kod yoluyla) dizine eklenmiş ifade yerine
dizi yöntemi.

Ayrıca, rxgen her biri için üç değerli makro tanımlar (yani başlık dosyasına ekler)
paket grubu: EN DÜŞÜK_OPCODE, HIGHEST_OPCODE ve
NUMBER_OPCODES. Bunlar için yararlı olabilir rxgen programcı. Ayrıca,
dikkat edin işlemkodu ifadesi isteğe bağlı bir özelliktir ve atlanabilir. böyle
durumlarda, otomatik işlem kodu numaraları 0'dan başlayarak sırayla oluşturulur.

İlk işlem kodu numarası kullanılarak değiştirilebilir. başlangıç ​​işlem kodu (bir eksikliği için
daha iyi isim) rxgen emretmek. Sözdizimi:

başlangıç ​​işlem kodu

nerede makul olmalı! Prosedürlerin karıştırılamayacağını unutmayın, bazıları
opcodes ve bazıları olmadan veya belirtilmesinden sonra opcode'lara izin verilmez.
başlangıç ​​işlem kodu ifadesi. rxgen tüm bu durumlarda şikayette bulunacaktır.

· tartışma giriş, prosedürün belirli bir parametresini temsil eder. Sözdizimi:

[IN | GİRİŞ | ÇIKIŞ | ]
[ |<>|[maks]|[]]

Tür dolaylı bir türse (yani, * ile takip ediliyorsa), işaretçinin
bir seviye takip edilmeli ve işaret edilen veriler iletilmelidir. Bu
normalde tüm yapılar/diziler ve çıkış parametreleri için kullanılır. Dikkat çekici bir istisna
açık dizi/yapı maksimum boyutunun verildiği zamandır; işaretçi dizisi olmadığından
bildirimlere izin verilir, benzer etkiyi elde etmek için typedefs kullanılmalıdır. bu
parametreler giriş parametreleri (öncesinde IN), çıkış parametreleri (öncesinde
OUT) veya giriş/çıkış parametreleri (öncesinde INOUT vardır). Belirtilmemişse, o zaman
prosedürde önceki parametrenin yönü kullanılır. (Not: ilk
parametreden önce yönlü ilkel gelmelidir!)

· "bölünmüş", dosya aktarımları veya herhangi bir
önce bilgi alışverişi yapması gereken diğer işlem (örneğin, bir dosyanın uzunluğu)
call, çıktı parametrelerini döndürür. Özel bir el sıkışma nedeniyle
uzaktan dosya aktarımı yaparken dahil, şu anda tüm bu tür çağrıları ikiye bölüyoruz
istemci tarafı saplama rutinleri. İlki ("Başla" ön ekiyle birlikte)
tüm IN ve INOUT parametrelerini sunucu tarafına iletin. İkincisi (varsayılan
"End" öneki, sunucudan INOUT ve OUT parametrelerini geri almak için kullanılır.
İki arama arasında, kullanıcının dosya için uygun aramaları yapması gerekir.
Aktar. Örneğin, AFS_ paketindeki aşağıdaki prosedür bildirimi

Getirme (IN a, b,INOUT c, OUT d) split = FETCHOPCODE;

kabaca iki bağımsız istemci saplama rutini oluşturur:

BaşlaAFS_Getir (IN a, b, c)

ve

EndAFS_Fetch(ÇIKIŞ c, d)

The bölünmüş önek ifadesi, ikisi tarafından kullanılan varsayılan önek adlarını değiştirmek için kullanılır.
dosya aktarımıyla ilgili prosedürle uğraşırken istemci tarafı saplama tarafından oluşturulan rutinler
aramalar. Örneğin:

splitprefix IN=Önce_ OUT=Sonra_

örneğin dosya aktarımıyla ilgili bir rutin için iki istemci stub'unun adlandırılmasına neden olur.
Gidip getirmek(), olmak Before_AFS_Fetch() ve After_AFS_Fetch(), Sırasıyla.

· "Çoklu" seçeneği, yukarıda açıklanan "bölme" özelliğiyle hemen hemen aynıdır. Tek
önemli görünür fark, iki istemci stub ile birlikte standart
istemci saplaması da oluşturulur. Amaç, çoklu Rx çağrılarını ele almak olduğundan, biz
çoklu Rx çağrısının olmadığı durumlarda tüm standart prosedür saplamasına ihtiyaç duyar.
prosedür gerçekleştirilir. "Çoklu" seçeneğin bir yan etkisi, bir
özel makro (yani, "çoklu_ "Başla" argümanları olarak geri dönen
ve başlık çıktı dosyasındaki "End" saplamaları. Bu makro doğrudan Rx kodu tarafından kullanılır
Bu prosedürün bir multi-Rx çağrısı yapıldığında.

ESKİ rxgen ÖZELLİKLER
Aşağıdaki rxgen komutları hala yürürlükte olmasına rağmen, yakında kaldırılacaktır.
daha iyi alternatifler var. ONLARI KULLANMAYIN!

The özel ifadesi, belirli verimsizlikleri gidermek için kullanılan geçici bir hack'tir.
bazı kullanıcı tarafından özelleştirilmiş bildirimleri işlemek için standart xdr rutinleri. Özellikle, bu
bir bildirimin parçası olarak belirtilen bir dize işaretçisine uygulanır. Örneğin,

özel yapı BBS SeqBody;

anlatır rxgen kullanıcı tanımlı BBS xdr rutinindeki "SeqBody" girişinin bir dize olduğunu (not
yapı başına birden fazla dize "özel" olabilir -- birden çok dize şu şekilde ayrılır:
virgül); bu nedenle, sunucu tarafından oluşturulan alanda düzgün bir şekilde alan tahsis edecek ve tahsisini kaldıracaktır.
IN veya INOUT parametresi olarak bu yapıyı içeren saplamalar.

için daha iyi bir alternatif özel olduğunu özelleştirilmiş ifadesi, bu sadece
"özelleştirilmiş" belirteç ve ardından RPCL'ye dayalı bir yapının düzenli bildirimi
tüzük. Bu durumda, beyan oluşturulan başlık dosyasına dahil edilecektir (-h
seçeneği) ancak bu yapı için xdr rutini oluşturulmayacak -- kullanıcı
Bugün nasılsın. Bu yapıdaki tüm işaretçi girişleri hatırlanacak, böylece yapı
sunucu saplamasında IN veya INOUT olarak kullanıldığında, hiçbir çekirdek sızıntısı meydana gelmez. Örneğin,
düşünmek

özelleştirilmiş yapı CBS {
uzun Seqlen;
karakter *SeqBody;
}

"xdr_CBS" rutini, DECODE xdr işlem kodu sırasında kullanıcı tarafından sağlanacaktır,
"SeqBody" dizesi için uygun alan ayrılır. Benzer şekilde, bu alan serbest bırakılır
ÜCRETSİZ xdr işlem kodu sırasında.

Not: Eski tarz "Dizi parametresi özellikleri" artık desteklenmiyor.

ÖRNEKLER


Mevcut RPC dili tarafından mevcut olmayan bazı gereksinimler olması durumunda,
bu veri türlerini tanımsız bırakarak bazı XDR rutinlerini özelleştirin. Her veri türü için
bu tanımsız ise, başına "xdr_" adı eklenmiş bir rutinin var olduğu varsayılacaktır.
ona. Seçilmiş bir dizi rxgen özellikler aşağıda sunulmuştur, ancak daha kapsamlı bir
bir (sendikalar, karmaşık örnekler, vb.) lütfen bkz. rpcgen Programlama Başlangıç Kılavuzu ve
harici Veri Temsil: güneş Teknik notlar.

Yazı tipleri
RPC typedef ifadesi, C typedef ile aynıdır (yani "typedef" ").
Varsayılan olarak, çoğu kullanıcı bildirimi (yani yapılar, birlikler, vb.) otomatik olarak
tarafından typedef'ed rxgen. Ayrıştırmayı kolaylaştırdığı için kullanımı tavsiye edilir. rxgen
komut.

Dizeler
C "char *" dize kuralı, genellikle amaçlandığı için biraz belirsizdir.
boş sonlandırılmış bir karakter dizisi anlamına gelir, ancak aynı zamanda bir işaretçiyi de temsil edebilir.
tek karakter, bir dizi karaktere işaretçi vb. RPC dilinde bir boş-
sonlandırılan dize, açık bir şekilde "dize" olarak adlandırılır. Örnekler,

string büyük isim<>;
dize adı ;
typedef dize cilt adı ;

Maksimum dize boyutunun isteğe bağlı olabileceğine (yukarıdaki "büyük ad" gibi) veya
tercihen veya köşeli parantez içinde belirtilir (yani, yukarıda "ad" ve "cilt adı"). İçinde
pratikte, arayüzlerde her zaman yalnızca sınırlı dizeler kullanılmalıdır. Örnek bir arama işlemi
yukarıdaki bildirimleri kullanmak şöyle olacaktır:

GetEntryByName (volname adı,
ÇIKIŞ yapısı vldbentry *giriş) = VL_GETENTRYBYNAME;

ya da tabii ki,

GetEntryByName (dize cilt adı ,
ÇIKIŞ yapısı vldbentry *giriş) = VL_GETENTRYBYNAME;

Kullanıcının dize parametrelerinin ne zaman olması gerektiğini anlaması çok önemlidir.
istemcisi ve/veya sunucu programları tarafından tahsis edilir ve/veya serbest bırakılır. hakkında kısa bir analiz
dize parametrelerinin işlenmesi aşağıdaki gibidir (işlem için benzer bir yöntemin kullanıldığını unutmayın).
daha sonra gösterileceği gibi değişken uzunluklu diziler):

· İstemci tarafında: IN ve INOUT string parametreleri programcının sorumluluğundadır.
ve rpc çağrılmadan önce (statik veya malloc aracılığıyla) tahsis edilmeli ve serbest bırakılmalıdır (eğer
malloc kullanıldı) kullanıcının istemci programında rpc'nin dönüşünden sonra; tabii ki, için
INOUT parametreleri, döndürülen dize, malloced giriş dizesinden daha büyük olamaz.

OUT dize parametreleri otomatik olarak değiştirilir (döndürülen
string ve maxsize değil) tarafından rxgen istemci taslakları (içinde Dosya.cs.c) ve olmalıdır
istemci programı tarafından serbest bırakıldı; Kuşkusuz, bu biraz kafa karıştırıcı olabilir çünkü kullanıcı
tahsis etmediği bir şeyi serbest bırakması gerekiyor.}

· Sunucu tarafında: IN ve INOUT dize parametreleri otomatik olarak değiştirilir (
gelen dizelerin boyutu) rxgen sunucu taslakları tarafından (içinde Dosya.ss.c) onlardan önce
kullanıcının sunucu prosedürüne geçirilir; bu alan hemen önce otomatik olarak serbest bırakılır
rxgen sunucu saplaması geri döner; bu nedenle kullanıcının IN için özel bir şey yapmasına gerek yoktur.
ve INOUT dize parametreleri.

OUT dize parametreleri, kullanıcının sunucu prosedürü tarafından değiştirilmelidir (yani boş gösterici
rxgen sunucu saplaması tarafından kendisine iletilir) ve sonunda otomatik olarak serbest bırakılır.
the rxgen sunucu saplaması. İstemci tarafında olduğu gibi, OUT parametreleri biraz
alışılmışın dışında (yani sunucu rutini bir dizgeyi kendisini serbest bırakmadan malloc yapmalıdır;
bu tarafından yapılır rxgen sunucu saplaması).

INOUT ve OUT dizi parametreleri için, hem istemci hem de sunucu tarafında
argümanlar işaretçilerin karakteri olmalıdır (yani char **).

İşaretçiler
RPC'deki işaretçi bildirimleri de tam olarak C'deki gibidir (yani "yapı
single_vldbentry *vldblist;"). Elbette, ağ üzerinden işaretçiler gönderilemez, ancak
Listeler ve ağaçlar gibi özyinelemeli veri türlerini göndermek için XDR işaretçileri kullanılabilir (bir
bağlantılı bir liste örneği birazdan gösterilecektir).

Diziler
Sabit diziler, standart C dizisi bildirimleri gibidir (yani "struct UpdateEntry
girişler[20]") içinde herhangi bir yan etki sorunu olmadan rxgen. Değişken uzunluklu diziler olduğundan
C'de açık bir sözdizimi yoktur, bunun için köşeli parantezler kullanılır ve dizi bildirimleri
aslında "yapı"larda derlenmiştir. Örneğin, aşağıdaki gibi beyanlar:

sabit MAKSBULKBOYUT = 10000;
const MAKSENTRİLER = 100;
opak yığın ; /* En fazla 10000 öğe */
int ana bilgisayarlar<>; /* herhangi bir sayıda öğe */
typedef vldbentry blkentries<100>; /* Tercih edilen dizi decl */

aşağıdaki yapılarda derlenir:

yapı {
u_int toplu_len; /* öğe sayısı */
char *bulk_val; /* diziye işaretçi */
} toplu;

"bulk" dizisi için ve benzer şekilde "blkentries<100>" dizisi için,

yapı {
u_int blkentries_len; /* dizideki öğe sayısı */
vldbentry *blkentries_val; /* diziye işaretçi */
} bloklar;

Bu nedenle kullanıcı, "sihirli" olarak oluşturulmuş yapı girişlerinin farkında olmalıdır.
dizideki öğe sayısı ( _len) ve dizinin işaretçisi
( _val) çünkü bazı girişlerin
istemci/sunucu programları. Örnek bir işlem şöyle olacaktır:

typedef vldbentry blkentries ;
proc GetBlk (OUT blok girişleri *vlentries) = VL_GETBLK;

veya daha doğrudan,

GetBlk(OUT vldbentry vlentries ) = VL_GETBLK;

İlk kullanım gerekmediğinden en son yöntemin tercih edilebileceğini unutmayın.
typedef deyimi (ve kuşkusuz, programcılar typedef'lerden kaçınmayı tercih ederler),
bunun farkına var rxgen yapı genişletmeyi ve xdr oluşturmayı örtük olarak yapar; Öyleyse
kullanıcı daha önce olduğu gibi "vldbentries_val" ve "vldbentries_len" alanlarından haberdar olmalıdır.
(aşağıdaki örneklere bakın).

Dizi örnek I (en az arzu edilir)

Arayüz konfigürasyonunda prosedür beyanı:

proc ListAttributes (vldblistbyattributes * öznitelikleri,
INOUT blkentries *vldbentries) = VL_LISTATTRIBUTES;

Örnek MÜŞTERİ kodu:

blkentries girişleri, *pnt;
input.blkentries_len = 10; /* maksimum # döndürülen girdi */
input.blkentries_val = (vldbentry *)malloc(LEN);
/* Ayarlanmalıdır */

kod = VL_ListAttributes(&attributes, &entries);
if (!kodu) {
pnt = input.blkentries_val;
için (i=0; i < input.blkentries_len; i++, pnt++)
display_vldbentry(pnt);
/* Ayrılan alanı boşalttığınızdan emin olun */
free((char *)entries.blkentries_val);
}

Örnek SUNUCU kodu:

VL_ListAttributes(öznitelikler, girişler)
{
vldbentry *singleentry = girişler->blkentries_val;
girişler->blkentries_len = 0;

while (copy_to_vldbentry(&vlentry, singleentry))
singleentry++, vldbentries->entries_len++;
}

Değişken boyutlu diziler için bu yöntem iyi çalışsa da, bazı önemli dezavantajlar vardır.
Dizi parametresi (yukarıdaki vldbentries) INOUT olarak bildirilmelidir, çünkü
beklenen döndürülen dizinin maksimum uzunluğunu iletin; daha da önemlisi, büyük (bağlı olarak
"_len") önemsiz kod parçasının değeri sonuç olarak sunucuya aktarılacak
dizinin IN(out) yan etkisi. kolay ve kullanışlı bir yöntemdir.
döndürülen dizi boyutu, baştan ve boyut oldukça yüksek olduğunda tahmin edilebilir. Bu
yöntemin hatalı kullanımına (ve kötüye kullanılmasına) bir örnek olarak dahil edilmiştir. rxgen ve olmamalı
Kullanılmış.

Dizi örnek II (Arzu edilen yöntem)

Arayüz konfigürasyonunda prosedür beyanı (yukarıdaki Örnek I kullanılarak):

proc ListAttributes (vldblistbyattributes * öznitelikleri,
OUT blkentries *vldbentries) = VL_LISTATTRIBUTES;

Örnek MÜŞTERİ kodu:

blkentries girişleri, *pnt;

kod = VL_ListAttributes(&attributes, &entries);
if (!kodu) {
pnt = input.blkentries_val;
için (i=0; i < input.blkentries_len; i++, pnt++)
display_vldbentry(pnt);
/* Ayrılan alanı boşalttığınızdan emin olun (rxgen tarafından) */
free((char *)entries.blkentries_val);
}

Örnek SUNUCU kodu:

VL_ListAttributes(öznitelikler, girişler)
{
vldbentry *tek giriş;
girişler->blkentries_len = 0;
singleentry = girişler->blkentries_val
= (vldbentry *)malloc(MAXENTRIES * sizeof(vldbentry));

while (copy_to_vldbentry(&vlentry, singleentry))
singleentry++, vldbentries->entries_len++;
}

Bu, değişken boyutlu dizileri çıktı parametresi olarak kullanmanın en iyi (ve en basit) yoludur.
sunucu tarafı saplamasının sorumluluğundadır. malloc () olan yeterli alan
tarafından otomatik olarak serbest bırakılır. rxgen Taslak; istemci tarafı tarafından ayrılan alanı boşaltmalı
the rxgen-arama saplaması.

Dizi örnek III (bağlı Listeler)

Aşağıdaki 3 bildirimi göz önünde bulundurarak (bazı optimizasyonlar uygulayabilirdi)
yapılandırma dosyası:

typedef yapı single_vldbentry *vldblist;
yapı single_vldbentry {
vldbentry vlentry;
vldblist next_vldb;
};

yapı vldb_list {
vldblist düğümü;
};

ve rxgen prosedür bildirimi:

LinkedList (vldblistbyattributes * özniteliklerinde,
ÇIKIŞ vldb_list *bağlı girişler) = VL_LINKEDLIST;

Örnek MÜŞTERİ kodu:

vldb_list bağlantılıvldbs;
vldblist vlist, vllist1;

bzero(&linkedvldbs, sizeof(vldb_list));
code = VL_LinkedList(&öznitelikler, &nentries, &linkedvldbs);
if (!kodu) {
printf("%d vldb girdisi aldık\n", yazılar);
for (vllist = bağlantılıvldbs.node; vllist; vllist = vllist1) {
vllist1 = vllist->next_vldb;
display_entry(&vllist->vlentry);
ücretsiz((char *)vlllist);
}
}

Örnek SUNUCU kodu:

VL_LinkedList(rxcall, öznitelikler, girişler, bağlantılıvldbs);
{
vldblist vllist, *vllistptr = &linkedvldbs->node;
sırasında (...) {
vllist = *vlistptr
= (single_vldbentry *)malloc (sizeof (single_vldbentry));
copy_to_vldbentry(&tentry, &vllist->vlentry);
kayıtlar++;
vllistptr = &vllist->next_vldb;
};
*vllistptr = BOŞ;
}

Bağlantılı liste kullanmanın birçok avantajı vardır: Sunucuya hiçbir şey iletilmez (parametre
OUT), ek bir ek yük söz konusu değildir ve arayanın açıkça
keyfi bir dönüş boyutu için hazırlanın. Bir dezavantajı, arayanın
Sorumluluğu malloc () (sunucuda) ve her girişin ücretsiz (istemcide)
istenmeyen çekirdek sızıntılarından kaçının). Diğer bir dezavantaj, özyinelemeli bir çağrı olduğundan, C
yığın, listedeki düğüm sayısına göre doğrusal olarak büyüyecektir (bu nedenle
büyük miktarda veri bekleniyorsa Rx LWP yığınını artırın - varsayılan yığın boyutu
4K'dır). Buradaki avantajlar dezavantajlardan daha ağır basmalıdır.

Yukarıdaki üç dizi örneğinin yorumlarına dikkat etmek önemlidir.
özellikle kullanıcının ne zaman alan ayırması/boşaltması gerektiğine atıfta bulunduklarında
değişken uzunluklu diziler Mekanizma, dizelerin işlenmesine çok benzer, bu nedenle
yukarıdaki dizeler bölümünü gözden geçirmeniz gerekebilir; bağlantılı listelerin işlendiğini unutmayın
biraz farklı...

Diğer örnekler
Aşağıda, bazı ortak özellikleri gösteren rastgele bir arayüz dosyasının kısaltılmış bir versiyonu bulunmaktadır.
vakalar.

/* R.xg komut dosyası arabirimi tarafından kullanılan tüm yapıların bildirimi */

yapı AFFSid {
imzasız uzun Cilt;
imzasız uzun Vnode;
imzasız uzun Benzersiz;
};

typedef uzun ViceDataType;

/* TEST'in yalnızca "HEADER" ile eşdeğer olacağını unutmayın.
başlığın işlenmesi, *.h, dosya */

#ifdef RPC_HDR
#define TEST "BAŞLIK"
#else
#define TEST "DİNLENME"
#endif

/* Bu standart *.xg belirtim dosyasıdır */

paket AFS_
splitprefix IN=ÖNCE_ÇIKIŞ=SONRA_;
Önek Testi

proc Remove(IN struct AFFSid *Yapıldı, IN string volname<64>,
ÇIKIŞ yapısı AFSStatus *Durum) = AFS_REMOVE;

FS bağlantısını kes AUX_disconnectFS() = AFS_DISCONNECTFS;

proc GetVolumeInfo(Dize Vid,
ÇIKIŞ yapısı VolumeInfo *Bilgi) = AFS_GETVOLUMEINFO;

/* Konfigürasyon başına birden fazla arayüze sahip olabilirsiniz */

paket VOTE_

/* "Çoklu" özelliği kullanarak; bu nedenle VOTE_Beacon bir
çoklu Rx araması veya normal arama olarak */

Beacon (uzun durumda, uzun oyBaşlat,
net_version *versiyon, net_tid *tid)
çoklu = VOTE_BEACON;

paket DISK_

/* "Bölme" özelliğini kullanma */

SendFile (uzun dosyada, uzun ofset,
uzun uzunluk, net_version *versiyon)
bölme = DISK_SENDFILE;

Çıktı of an gerçek arayüzey yapılandırma
tarafından üretilen gerçek çıktılardan bazılarını göstereceğiz. rxgen kısaltılmış olarak takip ederek
gerçek arayüz yapılandırması.

yapılandırma dosya

Arayüz yapılandırma dosyasının içeriği (vldbint.xg):

paket VL_
#include "vl_opcodes.h" /* İşlem kodları buraya dahil edilmiştir */
%#include "vl_opcodes.h" /* doğrudan başka yerlere */

/* Diğer paketleri etkileyen parametrelerdeki mevcut sınırlamalar
(yani hacim) */

sabit MAXNAMELEN = 65;
sabit MAXNSERVERS = 8;
sabit MAKSTİPLERİ = 3;

/* Tek bir vldb girişinin harici (görünür) temsili */

yapı vldbentry {
karakter adı[MAXNAMELEN];
uzun hacimType;
uzun nSunucuları;
uzun sunucuNumarası[MAXNSERVERS];
uzun serverPartition[MAXNSERVERS];
uzun serverFlags[MAXNSERVERS];
u_long birim kimliği[MAXTYPES];
uzun bayraklar;
};

typedef yapı single_vldbentry *vldblist;
yapı single_vldbentry {
vldbentry VldbEntry;
vldblist next_vldb;
};

yapı vldb_list {
vldblist düğümü;
};

/* vldb arayüz çağrıları */

CreateEntry (uzun Süreli,
vldbentry *yeni giriş) = VLCREATEENTRY;

GetEntryByName (dize birim adı İÇİNDE ,
ÇIKIŞ vldbentry *giriş) = VLGETENTRYBYNAME;

GetNewVolumeId (uzun çarpma sayımında,
OUT uzun *newvolumid) = VLGETNEWVOLUMEID;

ReplaceEntry (uzun Süreli,
uzun voltaj,
vldbentry *yeni giriş,
uzun ReleaseType) multi = VLREPLACEENTRY;

ListAttributes (VldbListByAttributes * özniteliklerinde,
DIŞI uzun *neler,
OUT vldbentry yığınları )
= VLLİSTATİFLİKLER;

LinkedList (VldbListByAttributes * öznitelikleri,
DIŞI uzun *neler,
ÇIKIŞ vldb_list *bağlı girişler) = VLLINKEDLIST;

R tarafından oluşturulan koddan bu yana yalnızca Rx tarafından oluşturulan koda odaklanacağız (-R opsiyon)
yakında eskiyecek. Rx ile ilgili aramalar hakkında ayrıntılı bir açıklama için
oluşturulan taslaklar (örn. rx_NewCall(), rx_EndCall()), neler olduğuna dair ayrıntılarla birlikte
belirli aramaların içinde (gibi xdrrx_create()) lütfen Rx belgelerine bakın. Yazıyor
"rxgen vldbint.xg", dört dosyanın oluşturulmasına neden olur: vldbint.h, vldbint.xdr.c,
vldbint.cs.c ve vldbint.ss.c. Bu dosyalara daha yakından bir bakış aşağıdadır.

üstbilgi dosya (vldbint.h)

/* Makine tarafından oluşturulan dosya -- DEĞİŞTİRMEYİN */

#include "vl_opcodes.h" /* doğrudan başka yerlere */
#define MAXNAMELEN 65
#define MAXNSERVERS 8
#define MAXTYPES 3

yapı vldbentry {
karakter adı[MAXNAMELEN];
uzun hacimType;
uzun nSunucuları;
uzun sunucuNumarası[MAXNSERVERS];
uzun serverPartition[MAXNSERVERS];
uzun serverFlags[MAXNSERVERS];
u_long birim kimliği[MAXTYPES];
uzun bayraklar;
};
typedef yapı vldbentry vldbentry;
bool_t xdr_vldbentry();

typedef yapı single_vldbentry *vldblist;
bool_t xdr_vldblist();

yapı single_vldbentry {
vldbentry VldbEntry;
vldblist next_vldb;
};
typedef yapı single_vldbentry single_vldbentry;
bool_t xdr_single_vldbentry();

yapı vldb_list {
vldblist düğümü;
};
typedef yapı vldb_list vldb_list;
bool_t xdr_vldb_list();

#Dahil etmek
#define multi_VL_ReplaceEntry(Volid, volttype, newentry, ReleaseType) \
multi_Body(StartVL_ReplaceEntry(multi_call, Volid, volttype,
yeni giriş, ReleaseType), EndVL_ReplaceEntry(çoklu arama))

typedef struct yığınları {
u_int toplu girişler_len;
vldbentry *bulkentries_val;
} yığınlar;
bool_t xdr_bulkentries();

/* Paket için opcode ile ilgili faydalı istatistikler: VL_ */
#VL_LOWEST_OPCODE 501'i tanımlayın
#VL_HIGHEST_OPCODE 506'yı tanımlayın
#define VL_NUMBER_OPCODES 6

Tüm yapıların otomatik olarak typedef'lendiğine ve tüm "const"'lerin dönüştürüldüğüne dikkat edin.
"#tanımla"lar. Toplu veriler gibi bazı veri yapıları prosedür parametrelerinden alınmıştır.
(ListAttributes proc'tan). Bu nedenle, taslaklar oluşturulurken bu akılda tutulmalıdır.
parça parça rxgen (yani, kullanarak -c, -h, -Cya da -S bayraklar). Ayrıca yanlardan biri
"multi" seçeneğinin etkileri ("ReplaceEntry" işleminde)
Yukarıdaki "multi_VL_ReplaceEntry".

XDR rutinleri için yapılar (vldbint.xdr.c)

/* Makine tarafından oluşturulan dosya -- DEĞİŞTİRMEYİN */

#Dahil etmek
#include "vldbint.h"

#include "vl_opcodes.h" /* doğrudan başka yerlere */

bool_t
xdr_vldbentry(xdrs, objp)
XDR *xdrs;
vldbentry *objp;
{
if (!xdr_vector(xdrs, (char *)objp->name, MAXNAMELEN,
sizeof(char), xdr_char))
dönüş (YANLIŞ);
if (!xdr_long(xdrs, &objp->volumeType))
dönüş (YANLIŞ);
if (!xdr_long(xdrs, &objp->nServers))
dönüş (YANLIŞ);
if (!xdr_vector(xdrs, (char *)objp->serverNumber, MAXNSERVERS,
sizeof(uzun), xdr_long))
dönüş (YANLIŞ);
if (!xdr_vector(xdrs, (char *)objp->serverPartition,
MAXNSERVERS, sizeof(uzun), xdr_long))
dönüş (YANLIŞ);
if (!xdr_vector(xdrs, (char *)objp->serverFlags, MAXNSERVERS,
sizeof(uzun), xdr_long))
dönüş (YANLIŞ);
if (!xdr_vector(xdrs, (char *)objp->volumeId, MAXTYPES,
sizeof(u_uzun), xdr_u_uzun))
dönüş (YANLIŞ);
if (!xdr_long(xdrs, &objp->flags))
dönüş (YANLIŞ);
dönüş (DOĞRU);
}

bool_t
xdr_vldblist(xdrs, objp)
XDR *xdrs;
vldblist *objp;
{
eğer (!xdr_pointer(xdrs, (char **)objp,
sizeof(yapı single_vldbentry),
xdr_single_vldbentry))
dönüş (YANLIŞ);
dönüş (DOĞRU);
}

bool_t
xdr_single_vldbentry(xdrs, objp)
XDR *xdrs;
single_vldbentry *objp;
{
if (!xdr_vldbentry(xdrs, &objp->VldbEntry))
dönüş (YANLIŞ);
if (!xdr_vldblist(xdrs, &objp->next_vldb))
dönüş (YANLIŞ);
dönüş (DOĞRU);
}

bool_t
xdr_vldb_list(xdrs, objp)
XDR *xdrs;
vldb_list *objp;
{
if (!xdr_vldblist(xdrs, &objp->düğüm))
dönüş (YANLIŞ);
dönüş (DOĞRU);
}

bool_t
xdr_bulkentries(xdrs, objp)
XDR *xdrs;
yığınlar *objp;
{
if (!xdr_array(xdrs, (char **)&objp->bulkentries_val,
(u_int *)&objp->bulkentries_len, MAXVLDBLEN,
sizeof(vldbentry), xdr_vldbentry))
dönüş (YANLIŞ);
dönüş (DOĞRU);
}

Unutmayın xdr_bulkentries() bir prosedürün yan etkisi olarak otomatik olarak oluşturulur
parametre bildirimi. Bu nedenle, aynı çoklu tip parametre bildirimleri kullanılırsa,
daha sonra çarpma tanımlı xdr_* taslakları oluşturulacak! Bunun daha iyi bir alternatif olduğunu hissettik
sahip olmak rxgen programcı, bulkentries_1, bulkentries_2... gibi türlerle ilgilenir.

İstemci Tarafı saplama rutinleri (vldbint.cs.c)

/* Makine tarafından oluşturulan dosya -- DEĞİŞTİRMEYİN */

#Dahil etmek
#Dahil etmek
#Dahil etmek
#include "vldbint.h"

#include "vl_opcodes.h" /* doğrudan başka yerlere */

int VL_CreateEntry(z_conn, Volid, yeni giriş)
struct rx_connection *z_conn'u kaydedin;
uzun Uçucu;
vldbentry * yeni giriş;
{
yapı rx_call *z_call = rx_NewCall(z_conn);
statik int z_op = 501;
int z_sonuç;
XDR z_xdrs;

xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

/* Argümanları sırala */
if ((!xdr_int(&z_xdrs, &z_op))
|| (!xdr_long(&z_xdrs, &Geçersiz))
|| (!xdr_vldbentry(&z_xdrs, yeni giriş))) {
z_sonuç = RXGEN_CC_MARSHAL;
başarısız ol;
}

z_sonuç = RXGEN_SUCCESS;
başarısız:
dönüş rx_EndCall(z_call, z_result);
}

int VL_GetEntryByName(z_conn, cilt adı, giriş)
struct rx_connection *z_conn'u kaydedin;
karakter * cilt adı;
vldbentry * girişi;
{
yapı rx_call *z_call = rx_NewCall(z_conn);
statik int z_op = 504;
int z_sonuç;
XDR z_xdrs;

xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

/* Argümanları sırala */
if ((!xdr_int(&z_xdrs, &z_op))
|| (!xdr_string(&z_xdrs, &cilt adı, 65))) {
z_sonuç = RXGEN_CC_MARSHAL;
başarısız ol;
}

/* Yanıt argümanlarının sırasını kaldır */
z_xdrs.x_op = XDR_DECODE;
if ((!xdr_vldbentry(&z_xdrs, giriş))) {
z_sonuç = RXGEN_CC_UNMARSHAL;
başarısız ol;
}

z_sonuç = RXGEN_SUCCESS;
başarısız:
dönüş rx_EndCall(z_call, z_result);
}

int VL_GetNewVolumeId(z_conn, bumpcount, yenihacim)
struct rx_connection *z_conn'u kaydedin;
uzun çarpma sayısı;
uzun * yeni hacimli;
{
yapı rx_call *z_call = rx_NewCall(z_conn);
statik int z_op = 505;
int z_sonuç;
XDR z_xdrs;

xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

/* Argümanları sırala */
if ((!xdr_int(&z_xdrs, &z_op))
|| (!xdr_long(&z_xdrs, &bumpcount))) {
z_sonuç = RXGEN_CC_MARSHAL;
başarısız ol;
}

/* Yanıt argümanlarının sırasını kaldır */
z_xdrs.x_op = XDR_DECODE;
if ((!xdr_long(&z_xdrs, yenihacim))) {
z_sonuç = RXGEN_CC_UNMARSHAL;
başarısız ol;
}

z_sonuç = RXGEN_SUCCESS;
başarısız:
dönüş rx_EndCall(z_call, z_result);
}

int VL_ReplaceEntry(z_conn, Volid, volttype, newentry, ReleaseType)
struct rx_connection *z_conn'u kaydedin;
uzun Volid, volttype, ReleaseType;
vldbentry * yeni giriş;
{
yapı rx_call *z_call = rx_NewCall(z_conn);
statik int z_op = 506;
int z_sonuç;
XDR z_xdrs;

xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

/* Argümanları sırala */
if ((!xdr_int(&z_xdrs, &z_op))
|| (!xdr_long(&z_xdrs, &Geçersiz))
|| (!xdr_long(&z_xdrs, &voltürü))
|| (!xdr_vldbentry(&z_xdrs, yeni girdi))
|| (!xdr_long(&z_xdrs, &ReleaseType))) {
z_sonuç = RXGEN_CC_MARSHAL;
başarısız ol;
}

z_sonuç = RXGEN_SUCCESS;
başarısız:
dönüş rx_EndCall(z_call, z_result);
}

int StartVL_ReplaceEntry(z_call, Volid, volttype, newentry, ReleaseType)
kayıt yapı rx_call *z_call;
uzun Volid, volttype, ReleaseType;
vldbentry * yeni giriş;
{
statik int z_op = 506;
int z_sonuç;
XDR z_xdrs;

xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

/* Argümanları sırala */
if ((!xdr_int(&z_xdrs, &z_op))
|| (!xdr_long(&z_xdrs, &Geçersiz))
|| (!xdr_long(&z_xdrs, &voltürü))
|| (!xdr_vldbentry(&z_xdrs, yeni girdi))
|| (!xdr_long(&z_xdrs, &ReleaseType))) {
z_sonuç = RXGEN_CC_MARSHAL;
başarısız ol;
}

z_sonuç = RXGEN_SUCCESS;
başarısız:
z_result döndür;
}

int EndVL_ReplaceEntry(z_call)
kayıt yapı rx_call *z_call;
{
int z_sonuç;
XDR z_xdrs;

z_sonuç = RXGEN_SUCCESS;
başarısız:
z_result döndür;
}

int VL_ListAttributes(z_conn, öznitelikler, kümeler, yığınlar_1)
struct rx_connection *z_conn'u kaydedin;
VldbListByAttributes * nitelikler;
uzun * girişler;
yığınlar * yığınlar_1;
{
yapı rx_call *z_call = rx_NewCall(z_conn);
statik int z_op = 511;
int z_sonuç;
XDR z_xdrs;

xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

/* Argümanları sırala */
if ((!xdr_int(&z_xdrs, &z_op))
|| (!xdr_VldbListByAttributes(&z_xdrs, nitelikler))) {
z_sonuç = RXGEN_CC_MARSHAL;
başarısız ol;
}

/* Yanıt argümanlarının sırasını kaldır */
z_xdrs.x_op = XDR_DECODE;
if ((!xdr_long(&z_xdrs, girişler))
|| (!xdr_bulkentries(&z_xdrs, bulkentries_1))) {
z_sonuç = RXGEN_CC_UNMARSHAL;
başarısız ol;
}

z_sonuç = RXGEN_SUCCESS;
başarısız:
dönüş rx_EndCall(z_call, z_result);
}

int VL_LinkedList(z_conn, öznitelikler, girişler, bağlantılı girişler)
struct rx_connection *z_conn'u kaydedin;
VldbListByAttributes * nitelikler;
uzun * girişler;
vldb_list * bağlantılı girişler;
{
yapı rx_call *z_call = rx_NewCall(z_conn);
statik int z_op = 512;
int z_sonuç;
XDR z_xdrs;

xdrrx_create(&z_xdrs, z_call, XDR_ENCODE);

/* Argümanları sırala */
if ((!xdr_int(&z_xdrs, &z_op))
|| (!xdr_VldbListByAttributes(&z_xdrs, nitelikler))) {
z_sonuç = RXGEN_CC_MARSHAL;
başarısız ol;
}

/* Yanıt argümanlarının sırasını kaldır */
z_xdrs.x_op = XDR_DECODE;
if ((!xdr_long(&z_xdrs, girişler))
|| (!xdr_vldb_list(&z_xdrs, bağlantılı girişler))) {
z_sonuç = RXGEN_CC_UNMARSHAL;
başarısız ol;
}

z_sonuç = RXGEN_SUCCESS;
başarısız:
dönüş rx_EndCall(z_call, z_result);
}

"Multi" özelliğinin yan etkisine dikkat edin ("ReplaceEntry" için üç farklı modül
işlem).

Sunucu Tarafı saplama rutinleri (vldbint.ss.c)

/* Makine tarafından oluşturulan dosya -- DEĞİŞTİRMEYİN */

#Dahil etmek
#Dahil etmek
#Dahil etmek
#include "vldbint.h"

#include "vl_opcodes.h" /* doğrudan başka yerlere */

uzun _VL_CreateEntry(z_call, z_xdrs)
yapı rx_call *z_call;
XDR *z_xdrs;
{
uzun z_result;
uzun Uçucu;
vldbentry yeni giriş;

if ((!xdr_long(z_xdrs, &Geçersiz))
|| (!xdr_vldbentry(z_xdrs, &yenientry))) {
z_sonuç = RXGEN_SS_UNMARSHAL;
başarısız ol;
}

z_result = VL_CreateEntry(z_call, Volid, &newentry);
başarısız:
z_result döndür;
}

uzun _VL_GetEntryByName(z_call, z_xdrs)
yapı rx_call *z_call;
XDR *z_xdrs;
{
uzun z_result;
char *hacimismi = (char *)0;
vldbentry girişi;

if ((!xdr_string(z_xdrs, &volumename, 65))) {
z_sonuç = RXGEN_SS_UNMARSHAL;
başarısız ol;
}

z_result = VL_GetEntryByName(z_call, &volumename, &entry);
z_xdrs->x_op = XDR_ENCODE;
if ((!xdr_vldbentry(z_xdrs, &giriş)))
z_sonuç = RXGEN_SS_MARSHAL;
başarısız:
z_xdrs->x_op = XDR_FREE;
if (!xdr_string(z_xdrs, &volumename, 65)) git fail1;
z_result döndür;
başarısız1:
RXGEN_SS_XDRFREE döndür;
}

uzun _VL_GetNewVolumeId(z_call, z_xdrs)
yapı rx_call *z_call;
XDR *z_xdrs;
{
uzun z_result;
uzun çarpma sayısı;
uzun yeni hacimli;

if ((!xdr_long(z_xdrs, &bumpcount))) {
z_sonuç = RXGEN_SS_UNMARSHAL;
başarısız ol;
}

z_result = VL_GetNewVolumeId(z_call, bumpcount, &newvolumid);
z_xdrs->x_op = XDR_ENCODE;
if ((!xdr_long(z_xdrs, &yenihacim)))
z_sonuç = RXGEN_SS_MARSHAL;
başarısız:
z_result döndür;
}

uzun _VL_ReplaceEntry(z_call, z_xdrs)
yapı rx_call *z_call;
XDR *z_xdrs;
{
uzun z_result;
uzun Volid, volttype, ReleaseType;
vldbentry yeni giriş;

if ((!xdr_long(z_xdrs, &Geçersiz))
|| (!xdr_long(z_xdrs, &volt türü))
|| (!xdr_vldbentry(z_xdrs, &yenientry))
|| (!xdr_long(z_xdrs, &ReleaseType))) {
z_sonuç = RXGEN_SS_UNMARSHAL;
başarısız ol;
}

z_result = VL_ReplaceEntry(z_call, Volid, volttype, &newentry,
Yayın Türü);
başarısız:
z_result döndür;
}

uzun _VL_ListAttributes(z_call, z_xdrs)
yapı rx_call *z_call;
XDR *z_xdrs;
{
uzun z_result;
VldbListByAttributes öznitelikleri;
uzun yazılar;
toplu girişler toplu girişler_1;

if ((!xdr_VldbListByAttributes(z_xdrs, &attributes))) {
z_sonuç = RXGEN_SS_UNMARSHAL;
başarısız ol;
}

z_result = VL_ListAttributes(z_call, &attributes, &nentries,
&bulkentries_1);
z_xdrs->x_op = XDR_ENCODE;
if ((!xdr_long(z_xdrs, &nentries))
|| (!xdr_bulkentries(z_xdrs, &bulkentries_1)))
z_sonuç = RXGEN_SS_MARSHAL;
başarısız:
z_xdrs->x_op = XDR_FREE;
if (!xdr_bulkentries(z_xdrs, &bulkentries_1)) git fail1;
z_result döndür;
başarısız1:
RXGEN_SS_XDRFREE döndür;
}

uzun _VL_LinkedList(z_call, z_xdrs)
yapı rx_call *z_call;
XDR *z_xdrs;
{
uzun z_result;
VldbListByAttributes öznitelikleri;
uzun yazılar;
vldb_list bağlantılı girişler;

if ((!xdr_VldbListByAttributes(z_xdrs, &attributes))) {
z_sonuç = RXGEN_SS_UNMARSHAL;
başarısız ol;
}

z_result = VL_LinkedList(z_call, &attributes, &nentries,
&bağlı girişler);
z_xdrs->x_op = XDR_ENCODE;
if ((!xdr_long(z_xdrs, &nentries))
|| (!xdr_vldb_list(z_xdrs, &bağlı girişler)))
z_sonuç = RXGEN_SS_MARSHAL;
başarısız:
z_result döndür;
}

uzun _VL_CreateEntry();
uzun _VL_GetEntryByName();
uzun _VL_GetNewVolumeId();
uzun _VL_ReplaceEntry();
uzun _VL_ListAttributes();
uzun _VL_LinkedList();

statik uzun (*StubProcsArray0[])() = {_VL_CreateEntry,
_VL_GetEntryByName, _VL_GetNewVolumeId, _VL_ReplaceEntry,
_VL_ListAttributes, _VL_LinkedList};

VL_ExecuteRequest(z_call)
kayıt yapı rx_call *z_call;
{
int işlemi;
XDR z_xdrs;
uzun z_result;

xdrrx_create(&z_xdrs, z_call, XDR_DECODE);
if (!xdr_int(&z_xdrs, &op))
z_sonuç = RXGEN_DECODE;
else if (op < VL_LOWEST_OPCODE || op > VL_HIGHEST_OPCODE)
z_sonuç = RXGEN_OPCODE;
başka
z_result = (*StubProcsArray0[op - VL_LOWEST_OPCODE])
(z_call, &z_xdrs);
z_result döndür;
}

Prosedürlerin işlem kodu dizisinde boşluklar varsa, kod VL_ExecuteRequest()
rutin büyük ölçüde farklı olurdu (bu,
her prosedür).

NOTLAR


rxgen Sun'dan uygulanıyor rpcgen Yarar. tüm standart rpcgen's
işlevsellik tamamen korunur. Dikkat edin, bazı aktif rpcgen geçerli olmayan seçenekler
için rxgen' amacına burada atıfta bulunulmamıştır (yani, -s, -l, -m seçenekler) ve ilgilenenler
okuyucu başvurmalı rpcgen(1) ayrıntılar için.

"%#include özellik kullanılır, sahip olmadığınızdan emin olun
rxgen sırasında sözdizimi hataları alacağınız için dil özellikleri (yani %#defines)
derlemeler..

Bu devam eden bir proje olduğundan, yukarıdakilerin çoğu büyük bir sorun olmadan değişebilir/kaybolabilir.
uyarı.

onworks.net hizmetlerini kullanarak rxgen'i çevrimiçi kullanın


Ücretsiz Sunucular ve İş İstasyonları

Windows ve Linux uygulamalarını indirin

  • 1
    xmlTV
    xmlTV
    XMLTV, işlenecek bir dizi programdır.
    TV (tvguide) listeleri ve yönetimine yardımcı olun
    TV izlemeniz, listeleri bir
    XML tabanlı biçim. yardımcı programlar var
    yap...
    XMLTV'yi indirin
  • 2
    grev
    grev
    Strikr Özgür Yazılım projesi. eserler
    'amaca dayalı' olarak yayınlandı
    ikili lisans: AGPLv3 (topluluk) ve
    CC-BY-NC-ND 4.0 uluslararası
    (reklam)...
    strikr'ı indir
  • 4
    GIFLIB
    GIFLIB
    giflib okumak için bir kütüphanedir ve
    gif görüntüleri yazma. API ve ABI'dır.
    olan libungif ile uyumlu
    LZW sıkıştırma sırasında geniş kullanım
    algoritma şuydu...
    GIFLIB'i indirin
  • 5
    Alt-F
    Alt-F
    Alt-F, ücretsiz ve açık bir kaynak sağlar
    DLINK için alternatif üretici yazılımı
    DNS-320/320L/321/323/325/327L and
    DNR-322L. Alt-F, Samba ve NFS'ye sahiptir;
    ext2/3/4'ü destekler...
    Alt-F'yi indirin
  • 6
    USM
    USM
    Usm, birleşik bir slackware paketidir
    otomatik işleyen yönetici
    bağımlılık çözünürlüğü birleştirir
    dahil olmak üzere çeşitli paket depoları
    gevşek yazılım, gevşek, p...
    usm'yi indir
  • Daha fazla »

Linux komutları

Ad