Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Explanation] HANDLE dan sedikit tentang API
13-07-2013, 03:02 PM, (This post was last modified: 13-07-2013, 03:33 PM by syahmiazhar.)
Post: #1
[Explanation] HANDLE dan sedikit tentang API
Assalamualaikum dan selamat sejahtera. Berikut adalah penjelasan tentang HANDLE dan sedikit tentang API. Bismillah... (hingga habis ayat). Moga ianya bermanfaat.

Handle didalam pengaturcaraan

Dalam kita membuat kod aturcara sama ada c/c++, php atau kod aturcara lain, mungkin kita pernah menggunakan handle sama ada sedar atau tidak. HANDLE ini biasanya didapati daripada memanggil fungsi pemula atau initialization. Fungsi ini akan memberikan HANDLE kepada pemanggil fungsi tersebut yang biasanya melalui kaedah pulangan nilai (return value).

Antara kod yang selalu kita dapati menggunakan handle seperti berikut:
C/C++
Code:
char buf[256];

FILE* fh = fopen("C:\\myfile.bin", "rb");
fread(buf, 256, 1, fh);
fclose(fh);
PHP
PHP Code:
$fh fopen("C:\\myfile.bin"“rb”);
$buf fread($fh256);
fclose($fh); 

Dalam kedua-dua contoh diatas, fh ialah HANDLE bagi fail yang kita buka, "c:\myfile.bin" melalui fungsi fopen. Kemudian, kita gunakan HANDLE tersebut untuk membaca fail yang kita buka tadi melalui fungsi fread. Akhir sekali, kita tutup fail menggunakan fungsi fclose, juga menggunakan HANDLE yang kita dapati daripada fopen tadi.

Banyak lagi API yang menggunakan HANDLE seperti Windows API, CURL API dan sebagainya. Dalam Windows API, kemungkinan kita akan dapati CreateFile() pulangkan HANDLE, CreateWindow() pulangkan HWND, manakala CURL seperti curl_easy_init() pulangkan CURL* sebagai HANDLE.

Jadi, apakah itu HANDLE?

HANDLE itu kita boleh anggap ia sebagai ID. Sebagai contoh, angka atau nombor kad pengenalan yang terdapat pada kad pengenalan di Malaysia. Kad pengenalan diberikan setelah selesai mendaftar di JPN dan pihak JPN boleh memberikan sebarang nombor pada kad pengenalan kita. Kemudian nombor kad pengenalan tersebut apabila disemak didalam sistem, ia boleh memaparkan maklumat tentang diri kita seperti nama, tarikh lahir, alamat, dan sebagainya. Kemudian, segala urusan kita dengan pihak kerajaan hampir semuanya memerlukan kita menyerahkan nombor kad pengenalan pada mereka.

HANDLE itu sebenarnya ia bersifat abstrak atau opaque, iaitu kita tidak tahu apa sebenarnya yang terdapat pada HANDLE tersebut. Ia ibarat karung berkunci, hanya API yang memberikan HANDLE boleh buka karung tersebut dan tahu apa yang terdapat pada karung itu. Begitu juga pada kad pengenalan, JPN boleh memberikan sebarang nombor pada kad pengenalan kita sedangkan kita tak tahu apa maksud sebenar keseluruhan angka yang terdapat pada kad pengenalan kita. Yang kita tahu ialah angka pada kad pengenalan kita adalah mewakili diri kita. samalah seperti contoh diatas dimana HANDLE fh mewakili C:\myfile.bin. Apabila kita diberi nombor kad pengenalan entah siapa-siapa, tak mungkin kita tahu ia milik siapa melainkan kita rujuk pada sistem terlebih dahulu.

Rahsia HANDLE

Ilmu Allah ibarat laut yang begitu luas, bahkan kalau air laut dijadikan dakwat, tujuh lautan sekalipun takkan mungkin habis. Mari kita selami dalam sedikit atau gali dalam sedikit apakah rahsia yang terdapat pada HANDLE.

Didalam php, variable (pembolehubah) boleh mewakili sebarang jenis data sama ada integer, double, string atau sebagainya dengan hanya letakkan simbol dolar dihadapan nama variable dan jenis data ditentukan oleh nilai. Manakala pada C/C++, terdapat sedikit kekangan. Nama variable mestilah dimulai dengan jenis data dan jenis data menentukan nilai yang boleh ditampung. Contoh int jumlah_kambing; iaitu jumlah_kambing hanya boleh dimasuki oleh data berjenis nomber integer. Didalam C/C++ juga terdapat hanya beberapa jenis data iaitu bool, char, int, short, long, float, double dan gabungan antaranya seperti short int, long long int dan sebagainya. Lihat contoh fopen diatas, FILE* ialah jenis data manakala fh ialah nama variable.

Mana datangnya data berjenis FILE*?

Kita lihat contoh lain, CreateFile() memulangkan data berjenis HANDLE, CreateWindow() memulangkan data berjenis HWND. Mana datangnya HANDLE dan HWND? Bukankah C/C++ hanya terdapat hanya beberapa jenis data sahaja yang disebutkan diatas tadi? Contoh lain lagi seperti API pada libcurl, curl_easy_init() memulangkan data berjenis CURL*.

Apabila kita trace jenis data tadi (di visual studio kita boleh klik kanan Go To Definition), kita akan dapati HANDLE adalah hasil dari typedef, CURL* adalah hasil dari typedef, FILE* juga adalah hasil dari typedef.

Code:
typedef void* HANDLE;
typedef void CURL

typedef merupakan satu kata kunci didalam C/C++ yang boleh memberikan nama lain pada jenis data yang sedia ada. Seperti diatas, HANDLE hanyalah merupakan void* dan CURL* merupakan void*.

void*(void pointer) ialah satu jenis data khas yang boleh menerima pointer (lokasi data pada memori bagi) sebarang jenis data lain. Selain itu, ia juga boleh menerima pointer struktur, fungsi, objek dan sebagainya. Untuk dapatkan nilai daripada void pointer, jenis data perlulah ditetapkan dahulu melalui kaedah type casting seperti contoh berikut.

Code:
int a = 15;
short b = 20;
float c = 25.4;

void* ptr;

ptr = &a;
printf("%d", *(int*)ptr);

//
// typecasting:
// *(int*)ptr apabila dipecahkan
//
//    int* pA = (int*)ptr; (dari void* ke int* - type cast)
//    int  A = *pA; (dari int* (pointer) ke int (nilai) – dereferencing)
//
//    printf("%d", A);
//

ptr = &b;
printf("%d", *(short*)ptr);

ptr = &c;
printf("%f", *(float*)ptr);

Setelah kita faham peranan void pointer (void*) mari kita lihat pula bagaimana pula ia berperanan didalam API. Sebelum itu, penulis ingin mengajak pembaca berfikir. Jikalau anda ingin mencipta sebuah kipas angin tanpa bilah atau sayap (bladeless fan kata mat salleh), anda tentulah tidak mahu penggunanya mengetahui bagaimana kipas tersebut beroperasi, bahan buatan, kaedah dan sebagainya. Jadi anda tutup dalamannya dengan badan kipas yang cantik dan dicat dengan warna yang menarik. Cukuplah sekadar mereka tahu pasang dan gunakan serta nampak cantik pada mata mereka. Jadi mereka tak perlu risaukan benda yang tidak sepatutnya dirisaukan. Mereka hanya boleh membayangkan apa yang terdapat didalam dan bagaimana ia beroperasi. Kalau anda buat badan kipas angin tersebut daripada kaca lutsinar ataupun tanpa badan terus, cuma rangka bagi mengekalkan posisi komponen sehingga nampaklah segala komponen dan susun atur dalamannya. Pengguna mungkin akan merasa risau, rasa celaru melihat kerumitan komponen, buat kritikan komponen dalaman, yang hebat sikit, cuba ubahsuai kipas tersebut (hack), dan yang paling hebat ialah meniru dan buat produk mereka sendiri (steal/counterfeit).

Begitulah juga dengan API, tujuan API adalah untuk membenarkan pengaturcara menggunakan produk mereka tanpa mereka perlu risaukan implementasi dalaman API tersebut. Jikalau anda ingin mencipta API untuk pengguna API membaca atau menulis fail, anda mungkin takrifkan seperti berikut

Code:
bool WriteFile(char* filename, int offset, char* data, int write_len);
bool ReadFile(char* filename, int offset, char* buffer, int read_len);

Dalam fungsi ini pertamanya apa yang perlu anda lakukan ialah mencari fail didalam ruangan storan iaitu dengan melintasi setiap direktori yang dinyatakan pada filename sehingga bertemu fail yang ingin dibuka. Kemudian, dari fail tersebut anda perlu dapatkan lokasi data sebenar dalam ruangan storan. Selepas lokasi data bagi fail tersebut ditemui, barulah data ditulis. Carian adalah suatu proses yang lambat. Bayangkan pengguna ingin menulis dalam fail yang sama beberapa kali, sudah tentu prestasi komputer akan menurun kerana proses carian.

Bagi mengatasi masalah ini, anda perlulah membuat satu lagi API iaitu OpenFile() dan gunakan teknik HANDLE iaitu memberi pemanggil satu nilai bagi mewakili fail yang dibuka.

Code:
int OpenFile(char* filename);
bool WriteFile(int file_handle, int offset, char* data, int write_len);
bool ReadFile(int file_handle, int offset, char* buffer, int read_len);

Fungsi OpenFile akan membuat carian fail dalam storan dan memulangkan lokasi data sebenar pada pemanggil sebagai HANDLE. Pemanggil yang tidak tahu apa yang diwakili HANDLE akan menganggap ia cuma sebagai fail yang dibuka sedangkan bagi penulis API, ia mewakili lokasi data bagi fail tersebut.

Bagi menyorokkan lagi, penulis API bolehlah menggunakan teknik type casting, iaitu mengubah sesuatu jenis data kepada jenis data yang lain, seperti int (integer) kepada void* (void pointer).

API anda terlalu ringkas dan biasa, pengguna API memerlukan API yang boleh boleh melindungi fail daripada ditulis atau dibaca. Bagi memnuhi permintaan pengguna, anda naik taraf API anda seperti berikut.

Code:
int OpenFile(char* filename, bool can_read, bool can_write);

Apabila pemanggil memberi nilai false pada can_read, maka fungsi ReadFile() akan gagal dan sebaliknya, begitu juga bagi can_write, apabila nilai false diberikan, fungsi WriteFile() akan gagal. Bagi menggagalkan ReadFile() apabila can_read = false, maka anda perlulah memberitahu fungsi ReadFile() bahawa pemanggil awal-awal telah menetapkan can_read = false. Cara yang mudah bagi situasi ini ialah memulangkan ketiga-tiga data iaitu lokasi data, can_read serta can_write dengan membuat satu struktur (struct) didalam memori dan memulangkan pada pemanggil sebagai HANDLE. Kemudian pada fungsi ReadFile()/WriteFile(), ujian akan dilakukan sebelum operasi tulis/baca dilakukan.

Code:
struct TOpenFile {    
    int data_location;
    bool can_read;
    bool can_write;
}

TOpenFile* OpenFile(char* filename, bool can_read, bool can_write)
{
    TOpenFile* handle = malloc(sizeof( TOpenFile ));
    int data_location = find_data_for_file( filename );

    handle->can_read = can_read;
    handle->can_write = can_write;

    ...

    handle->data_location = data_location;
    
    return handle;
}

bool WriteFile(TOpenFile* handle, int offset, char* data, int write_len)
{
    if (handle->can_write == false) return false;

    ...
}

void CloseFile(TOpenFile* handle)
{
    free( handle );
}

Disebabkan kita buat memperuntukkan sebahagian memori untuk handle menggunakan malloc, maka kita perlukan satu lagi API bagi membebaskan ruangan memori yang telah digunakan. Jadi kita namakan sebagai CloseFile() dan mensyaratkan kepada pengguna API supaya memanggil fungsi ini apabila fail tidak lagi digunakan.

Apabila kita memulangkan struktur, ia seolah-olah seperti kipas tanpa badan tadi. API tersebut akan kelihatan rumit pada penulis aturcara dan yang hebat sikit mungkin akan hack. Sebagai contoh, nilai can_write daripada false ditukar menjadi true. Bagi menyembunyikan struktur TOpenFile, teknik type casting dan void pointer bolehlah digunakan.

Code:
typedef void* MYHANDLE;

MYHANDLE OpenFile(char* filename, bool can_read, bool can_write)
{
    TOpenFile* handle = malloc(sizeof( TOpenFile ));
    
    ...
    
    return (MYHANDLE) handle;
}    

bool WriteFile(MYHANDLE handle, int offset, char* data, int write_len)
{
    TOpenFile* p = (TOpenFile*) handle;
    if (p->can_write == false) return false;

    ...
}

Cara ini mempunyai kelebihan iaitu kita tidak mendedahkan dalaman bagaimana API kita berfungsi, ia sekaligus memudahkan penulis aturcara menggunakan API kita kerana tidak kelihatan rumit. Jadi apabila anda melihat HANDLE dalam API, maka ketahuilah ia adalah satu perwakilan dan kebanyakannya bersifat opaque. Jika anda ingin menulis API terutama bagi pengguna C, gunakan kaedah ini. C++ anda mempunyai pilihan nak menulis cara C atau boleh gunakan class dengan kaedah encapsulation.

Maka tamatlah sudah artikel ini, semoga ia bermanfaat dan difahami oleh pembaca sekalian.

Terima kasih kerana membaca. Andai ada salah dan silap tolong betulkan.

Artikel khas ditujukan untuk shahril Big Grin Amek.. baca panjang2 ni ha.. hehe... Maaf takde kaler2 kalini...
Reply
13-07-2013, 04:00 PM,
Post: #2
RE: [Explanation] HANDLE dan sedikit tentang API
wow, mohon kongsi2 tutorial lain sama Big Grin
puas sudah menanam ubi, nenas juga dibeli orang, puas sudah aku berbakti, pengganas juga dipandang orang

Quote:A true warrior need blood on his sword; A true pirate never afraid to sail the red sea.
Reply
13-07-2013, 04:01 PM,
Post: #3
RE: [Explanation] HANDLE dan sedikit tentang API
Jadi pelik bila baca benda ni dalam bm.
  ▲  ʙᴇ ɴɪᴄᴇ ᴛᴏ ᴏᴛʜᴇʀs
▲ ▲ ( ⌣́,   ⌣̀ )\(^◡^ )[Image: ?r=OrangeCoral]

Reply
13-07-2013, 05:01 PM, (This post was last modified: 13-07-2013, 05:06 PM by syahmiazhar.)
Post: #4
RE: [Explanation] HANDLE dan sedikit tentang API
(13-07-2013, 04:01 PM)Codeshift3r Wrote: Jadi pelik bila baca benda ni dalam bm.
Ada rasa nak gelak tak? hehe
Reply
13-07-2013, 06:15 PM,
Post: #5
RE: [Explanation] HANDLE dan sedikit tentang API
Artikel yang bagus. Kena tunggu aku bukak pc untuk bagi +rep

Sent from my HTC One using Tapatalk 4 Beta

  ▲
▲ ▲
Spoiler:

surah Ali Imran Ayat 31

Reply
13-07-2013, 06:36 PM,
Post: #6
RE: [Explanation] HANDLE dan sedikit tentang API
nice, dh faham sikit2 tentang handle, tenks sifu syahmmiihh ;d
nk create api tu pening sikit, maybe study lebih sikit nnti faham kot ;d
Reply
13-07-2013, 11:29 PM,
Post: #7
RE: [Explanation] HANDLE dan sedikit tentang API
woah. sangat bagus, tapi aku xpaham sebab basic pun terumbang ambing. mohon shahril buat tuts for dummies macam aku OK
[Image: sudoes.png]
Reply
14-07-2013, 06:28 AM,
Post: #8
RE: [Explanation] HANDLE dan sedikit tentang API
(13-07-2013, 11:29 PM)red_fox Wrote: woah. sangat bagus, tapi aku xpaham sebab basic pun terumbang ambing. mohon shahril buat tuts for dummies macam aku OK

http://www.learncpp.com/

aku belajar dkt situ skrg, InsyaAllah faham, tuto dia pon senang nak ikut Big Grin
Reply
14-07-2013, 02:11 PM, (This post was last modified: 14-07-2013, 02:15 PM by Muhammad.)
Post: #9
RE: [Explanation] HANDLE dan sedikit tentang API
best guna windows api function ;d. make sure declare elok2 ape2 function tu punya parameter. sesetengah function advance sikit sbb dia punya parameter pointer to pointer. ini yg mencabar ak rasa bila guna windows api ni, nk casting input/output supaya boleh chainkan dgn function2 lain. ade pointer to structure la, pointer to pointer to structure laaa. fenin den. basic concept on pointer dlm c ko kene faham betul2 ;d. pastu byk2kan rujuk kat msdn on documentation function2 tu.
Reply
14-07-2013, 03:49 PM,
Post: #10
RE: [Explanation] HANDLE dan sedikit tentang API
(14-07-2013, 02:11 PM)Muhammad Wrote: best guna windows api function ;d. make sure declare elok2 ape2 function tu punya parameter. sesetengah function advance sikit sbb dia punya parameter pointer to pointer. ini yg mencabar ak rasa bila guna windows api ni, nk casting input/output supaya boleh chainkan dgn function2 lain. ade pointer to structure la, pointer to pointer to structure laaa. fenin den. basic concept on pointer dlm c ko kene faham betul2 ;d. pastu byk2kan rujuk kat msdn on documentation function2 tu.

this one explain alot GayFace
Hacking Its Not Nice
[Image: sig_9047_1.png]
Reply
14-07-2013, 11:24 PM, (This post was last modified: 14-07-2013, 11:25 PM by syahmiazhar.)
Post: #11
RE: [Explanation] HANDLE dan sedikit tentang API
WIN32 API nak faham tak susah tak senang Smile

Code:
#include <windows.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    WIN32_FIND_DATA FindData;
    HANDLE hFind;
    
    hFind = FindFirstFile( "C:\\*", &FindData );

    if (hFind != INVALID_HANDLE_VALUE) {

        do {

            printf( "%s\n", FindData.cFileName );

        } while( FindNextFile(hFind, &FindData) );

        FindClose( hFind );
    }

    return 0;
}

Contoh lain dalam win32 api yang gunakan handle ialah, FindFirstFile/FindNextFile/FindClose. Kalau lihat pada documentation kat msdn tu, FindFirstFile dia tulis begini:

Searches a directory for a file or subdirectory with a name that matches a specific name (or partial name if wildcards are used). - Cari file dan subdirectory dalam directory berdasarkan kriteria yang diberikan...

Code:
HANDLE WINAPI FindFirstFile(
  _In_   LPCTSTR lpFileName,
  _Out_  LPWIN32_FIND_DATA lpFindFileData
);

Jadi kita boleh buat kesimpulan, FindFirstFile return HANDLE serta menerima 2 parameter. Parameter pertama adalah berjenis input dan kedua adalah output. Lihat sebelum data type LPCTSTR dan LPWIN32_FIND_DATA ada annotation _In_ dan _Out_ (dikenali sebagai SAL). WINAPI tu pula sebagai calling convention, tidak akan diterangkan disini.

Kemudian baca penerangan bahagian parameter pertama:
LPCTSTR lpFileName Wrote:ia menerima input direktori atau path serta boleh mempunyai wildcard. Tak boleh terima NULL, string yang tak betul atau path ending dengan \.

Parameter kedua:
LPWIN32_FIND_DATA lpFindFileData Wrote:Pointer kepada struktur WIN32_FIND_DATA, struktur ini akan menerima maklumat tentang file/direktori yang dijumpai.

Lihat contoh kod diatas, cara guna API tersebut. Parameter pertama kita kasi "C:\\*", manakala parameter kedua kita kasi pointer kepada WIN32_FIND_DATA. Kemudian dia return HANDLE, gunakan HANDLE tu untuk API yang berkaitan. Yang lain tu boleh baca sendiri...
Reply
15-07-2013, 11:33 AM, (This post was last modified: 15-07-2013, 11:34 AM by fatah.)
Post: #12
RE: [Explanation] HANDLE dan sedikit tentang API
aku rasa dulu masa install vb6, akan bagi software tambahan, ku rasa nama dia win32 api viewer. dalam tu adalah senarai windows api functions & cara mau pakai. mungkin ini.

[Image: apv2002.jpg]

http://www.activevb.de/rubriken/apiviewe...ml#anchor3
̿ ̿ ̿̿'̿̿\̵͇̿̿\=(•̪●)=/̵͇̿̿/'̿̿ ̿ ̿ ̿ - انا کڤيتݢولوڠ
http://fatah.afraid.org/
[Image: 763440762.png]
Reply
16-07-2013, 12:27 AM,
Post: #13
RE: [Explanation] HANDLE dan sedikit tentang API
zaman kegemilangan vb6 dulu Big Grin hampir semua param guna long... hehe... Nama dia API Text Viewer... sekali bundle dalam vs6...
Reply
16-07-2013, 10:54 AM, (This post was last modified: 16-07-2013, 11:09 AM by fatah.)
Post: #14
RE: [Explanation] HANDLE dan sedikit tentang API
Yeah API Text Viewer. Zaman kegemilangan vb6 & kau masih muda. You must be super cool. GayFace

ku rasa ada satu site bagi documentation untuk extra/advance api & sample vb6 library

http://www.vbaccelerator.com/home/VB/index.asp
̿ ̿ ̿̿'̿̿\̵͇̿̿\=(•̪●)=/̵͇̿̿/'̿̿ ̿ ̿ ̿ - انا کڤيتݢولوڠ
http://fatah.afraid.org/
[Image: 763440762.png]
Reply


Forum Jump: