Bagikan melalui


Teknik IDL untuk Antarmuka dan Desain Metode yang Lebih Baik

Pertimbangkan untuk menggunakan teknik khusus IDL berikut untuk meningkatkan keamanan dan performa saat Anda mengembangkan antarmuka dan metode RPC yang menangani data yang sesuai dan varian. Atribut yang dimaksud dalam topik ini adalah atribut IDL yang diatur pada parameter metode yang menangani data yang sesuai (misalnya, atribut [size_is] dan [max_is]) atau data varian (misalnya, atribut [length_is] dan [string]).

Menggunakan atribut [range] dengan Parameter Data Yang Sesuai

Atribut [range] menginstruksikan run-time RPC untuk melakukan validasi ukuran tambahan selama proses unmarshaling data. Secara khusus, ia memverifikasi bahwa ukuran data yang disediakan diteruskan karena parameter terkait berada dalam rentang yang ditentukan.

Atribut [range] tidak memengaruhi format kawat.

Jika nilai pada kawat berada di luar rentang yang diizinkan, RPC akan memberikan pengecualian RPC_X_INVALID_BOUND atau RPC_X_BAD_STUB_DATA. Ini menyediakan tingkat validasi data tambahan, dan dapat membantu mencegah kesalahan keamanan umum seperti buffer overruns. Demikian juga, menggunakan [rentang] dapat meningkatkan performa aplikasi, karena data yang sesuai yang ditandai dengannya memiliki batasan yang ditentukan dengan jelas yang tersedia untuk dipertimbangkan oleh layanan RPC.

Aturan Manajemen Memori Stub Server RPC

Penting untuk memahami aturan manajemen memori stub server RPC saat membuat file IDL untuk aplikasi yang mendukung RPC. Aplikasi dapat meningkatkan pemanfaatan sumber daya server dengan menggunakan [rentang] bersama dengan data yang sesuai seperti yang ditunjukkan di atas, serta dengan sengaja menghindari penerapan atribut IDL data panjang variabel seperti [length_is] untuk data yang sesuai.

Aplikasi [length_is] ke bidang struktur data yang ditentukan dalam file IDL tidak disarankan.

Praktik Terbaik untuk Parameter Data Panjang Variabel

Berikut ini adalah beberapa praktik terbaik yang perlu dipertimbangkan saat menentukan atribut IDL untuk struktur data berukuran variabel, parameter metode, dan bidang.

  • Gunakan korelasi dini. Umumnya lebih baik untuk menentukan parameter ukuran variabel atau bidang sehingga terjadi segera setelah jenis integral pengontrol.

    Contohnya,

    earlyCorr
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long size, 
    [in,size_is(size)] char *pv
    );
    

    lebih baik dari

    lateCorr
    (
    [in,size_is(size)] char *pv, 
    [in, range(MIN_COUNT, MAX_COUNT)] long size)
    );
    

    di mana earlyCorr mendeklarasikan parameter ukuran segera sebelum parameter data panjang variabel, dan lateCorr mendeklarasikan parameter ukuran setelahnya. Menggunakan korespondensi awal meningkatkan performa secara keseluruhan, terutama dalam kasus di mana metode ini sering dipanggil.

  • Untuk parameter yang ditandai dengan tuple atribut [out, size_is], dan di mana panjang data diketahui di sisi klien atau di mana klien memiliki batas atas yang wajar, definisi metode harus mirip dengan yang berikut dalam hal atribusi dan urutan parameter:

    outKnownSize
    (
    [in,range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out,size_is(lSize)] UserDataType * pArr
    );
    

    Dalam hal ini, klien menyediakan buffer ukuran tetap untuk pArr, memungkinkan layanan RPC sisi server untuk mengalokasikan buffer berukuran cukup besar dengan tingkat jaminan yang baik. Perhatikan bahwa dalam contoh data diterima dari server ([out]). Definisinya mirip untuk data yang diteruskan ke server ([in]).

  • Untuk situasi di mana komponen sisi server dari aplikasi RPC memutuskan panjang data, definisi metode harus mirip dengan yang berikut:

    typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG;
    
    outUnknownSize
    (
    [out] RANGED_LONG *pSize,
    [out,size_is(,*pSize)] UserDataType **ppArr
    );
    

    RANGED_LONG adalah jenis yang ditentukan untuk stub klien dan server, dan dengan ukuran tertentu yang dapat diantisipasi klien dengan benar. Dalam contoh, klien meneruskan ppArr sebagai NULL, dan komponen aplikasi server RPC mengalokasikan jumlah memori yang benar. Setelah kembali, layanan RPC di sisi klien mengalokasikan memori untuk data yang dikembalikan.

  • Jika klien ingin mengirim subset array konforman besar ke server, aplikasi dapat menentukan ukuran subset seperti yang ditunjukkan dalam contoh berikut:

    inConformantVaryingArray
    (
    [in,range(MIN_COUNT,MAX_COUNT)] long lSize,
    [in] long lLength, 
    [in,size_is(lSize), length_is(lLength)] UserDataType *pArr
    );
    

    Dengan cara ini RPC hanya akan mengirimkan elemen lLength dari array di seluruh kawat. Namun, definisi ini memaksa layanan RPC untuk mengalokasikan memori ukuran lSize di sisi server.

  • Jika komponen aplikasi klien menentukan ukuran maksimum array yang dapat dikembalikan server, tetapi memungkinkan server untuk mengirimkan subset array tersebut, aplikasi dapat menentukan perilaku seperti itu dengan menentukan IDL yang mirip dengan contoh berikut:

    inMaxSizeOutLength
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out] long *pLength,
    [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr
    );
    

    Komponen aplikasi klien menentukan ukuran maksimum array, dan server menentukan berapa banyak elemen yang ditransmisikan kembali ke klien.

  • Jika komponen aplikasi server perlu mengembalikan string ke komponen aplikasi klien, dan jika klien tahu ukuran maksimum yang akan dikembalikan dari server, aplikasi dapat menggunakan jenis string yang sesuai seperti yang ditunjukkan dalam contoh berikut:

    outStringKnownSize
    (
    [in,range(MIN_COUNT, MAX_STRING)] long lSize,
    [out,size_is(lSize),string] wchar_t *pString
    );
    
  • Jika komponen aplikasi klien tidak boleh mengontrol ukuran string, layanan RPC dapat secara khusus mengalokasikan memori seperti yang ditunjukkan dalam contoh berikut:

    outStringUnknownSize
    (
    [out] LPWSTR *ppStr
    );
    

    Komponen aplikasi klien harus mengatur ppStr ke NULL saat memanggil metode RPC.