Rumah >hujung hadapan web >tutorial js >Gunakan C/C untuk melaksanakan modul Node.js (2)_node.js

Gunakan C/C untuk melaksanakan modul Node.js (2)_node.js

WBOY
WBOYasal
2016-05-16 16:35:311119semak imbas

Mengkaji masa lalu dan mempelajari perkara baharu boleh menggembirakan anda

Pertama sekali, sila ingat manual dalam talian V8 ini - http://izs.me/v8-docs/main.html.

Adakah anda masih ingat fail building.gyp dari kali terakhir?

Salin kod Kod adalah seperti berikut:

{
"sasaran": [
{
"target_name": "tambah",
"sumber": [ "addon.cc" ]
}
]
}

Sama seperti ini, jika anda mempunyai beberapa fail *.cc lagi, ia akan kelihatan seperti ini:
"sources": [ "addon.cc", "myexample.cc" ]

Kali terakhir kami memisahkan dua langkah sebenarnya, konfigurasi dan kompilasi boleh disatukan:
$ node-gyp configure build

Adakah anda sudah selesai membuat semakan? tanpa? !

Baiklah, mari teruskan.

Jadual Kandungan

Parameter fungsi

Kini kita akhirnya perlu bercakap tentang parameter.

Mari kita bayangkan bahawa terdapat fungsi add(a, b) sedemikian yang mewakili penambahan a dan b dan mengembalikan hasilnya, jadi tulis dahulu rangka fungsi:

Salin kod Kod adalah seperti berikut:

#include
menggunakan ruang nama v8;

Kendalikan(Const Arguments& args)
{
Skop HandleScope;

//... Di sini kita pergi lagi!
}

Hujah

Ini ialah parameter fungsi. Mari kita lihat rujukan manual rasmi v8 dahulu.
•int Length() const
•Pengendali tempatan[](int i) const

Kami tidak peduli tentang yang lain, kedua-dua ini penting! Satu mewakili bilangan parameter yang dihantar ke dalam fungsi, dan kurungan lain digunakan untuk mengakses parameter ke-n melalui indeks subskrip.

Oleh itu, kita boleh memahami secara kasar keperluan di atas sebagai args. Length() ialah 2, args[0] mewakili a dan args[1] mewakili b. Dan kita perlu menentukan bahawa jenis kedua-dua nombor ini mestilah Nombor.

Perhatikan bahawa pengendali indeks dalam kurungan segi empat sama mengembalikan Local, iaitu kelas asas semua jenis dalam Node.js. Oleh itu, parameter yang diluluskan adalah jenis yang tidak pasti, dan kita mesti menentukan sendiri apakah parameter tersebut. Ini berkaitan dengan beberapa fungsi jenis Nilai ini.

•IsArray()
•IsBoolean()
•IsDate()
•IsFunction()
•IsInt32()
•IsNativeError()
•IsNull()
•IsNumber()
•IsRegExp()
•IsString()
•...

Saya tidak akan menyenaraikannya satu persatu, anda boleh membaca dokumentasi untuk selebihnya. 。:.゚ヽ(*´∀`)ノ゚.:。

ThrowException

Ini adalah fungsi yang akan kami gunakan nanti. Butiran boleh didapati dalam dokumentasi v8.

Seperti namanya, ia menimbulkan ralat. Selepas melaksanakan penyataan ini, ia adalah bersamaan dengan melaksanakan penyataan throw() dalam fail setempat Node.js. Contohnya:
ThrowException(Exception::TypeError(String::New("Nombor argumen yang salah")));

Ia bersamaan dengan melaksanakan Node.js:
buang TypeError baru("Bilangan argumen yang salah");

Undefined()

Fungsi ini juga terdapat dalam dokumentasi.

Secara khusus, ia adalah nilai nol, kerana sesetengah fungsi tidak perlu mengembalikan sebarang nilai tertentu, atau tiada nilai pulangan Pada masa ini, Undefined() perlu digunakan.

Jom lakukannya, Saonian!

Selepas memahami perkara di atas, saya percaya anda akan dapat menulis logik a b tidak lama lagi. Saya akan menyalin kod daripada manual rasmi Node.js dan memberikannya kepada anda untuk melalui:

Salin kod Kod adalah seperti berikut:

#include
menggunakan ruang nama v8;

Kendalikan(Const Arguments& args)
{
Skop HandleScope;

// bermaksud lebih daripada 2 parameter boleh dihantar, tetapi sebenarnya kami hanya menggunakan dua yang pertama
If(args.Length() < 2)
{
// ​ ralat lontaran
         ThrowException(Exception::TypeError(String::New("Nombor hujah salah")));

// Kembalikan nilai nol
          kembali skop. Tutup(Tidak Ditakrifkan());
}

// Jika salah satu daripada dua parameter pertama bukan nombor
If(!args[0]->IsNumber() || !args[1]->IsNumber())
{
                 // Lemparkan ralat dan kembalikan nilai nol
         ThrowException(Exception::TypeError(String::New("Argumen salah")));
          kembali skop. Tutup(Tidak Ditakrifkan());
}

// Sila rujuk dokumentasi v8 untuk butiran
// http://izs.me/v8-docs/classv8_1_1Value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// Fungsi `NumberValue`
Setempat num = Number::New(args[0]->NumberValue() args[1]->NumberValue());

kembalikan skop. Tutup(bilangan);
}

Fungsi selesai!

Akhir sekali, tulis fungsi eksport pada penghujung dan ia OK.

Salin kod Kod adalah seperti berikut:

void Init(Mengendalikan eksport)
{
eksport->Set(String::NewSymbol("add"),
FunctionTemplate::Baharu(Tambah)->GetFunction());
}

MODUL_NODE(tambahan, Init)


Selepas anda menyusunnya, kita boleh menggunakannya seperti ini:

Salin kod Kod adalah seperti berikut:
var addon = require('./build/Release/ addon') ;
console.log(addon.add(1, 1) "b");

Anda akan melihat 2b! ✧。٩(ˊᗜˋ)و✧*。

Fungsi panggil balik

Dalam bab lepas, kami hanya bercakap tentang Hello world Dalam bab ini, Nenek membuat penemuan secara sedar dan menulis fungsi panggil balik yang lain.

Seperti biasa, kami menulis rangka kerja dahulu:

Salin kod Kod adalah seperti berikut:

#include
menggunakan ruang nama v8;

Kendalikan RunCallback(Const Arguments& args)
{
Skop HandleScope;

// ... berderak berderak

kembalikan skop. Tutup(Tidak Ditakrifkan());
}

Kemudian kami memutuskan untuk menggunakannya seperti ini:
func(function(msg) {
console.log(msg);
});

Iaitu, ia akan menghantar parameter ke fungsi panggil balik Kami membayangkan ia adalah rentetan, dan kemudian kami boleh console.log() keluar.

Mula-mula anda perlu mempunyai siri rentetan

Tanpa berlengah-lengah lagi, mari kita berikan satu rentetan dahulu dan kemudian bercakap mengenainya. (√ ζ ε:)

Tetapi kita perlu menjadikan rentetan ini jenis universal, kerana kod Node.js ditaip dengan lemah.
Setempat::Baharu(String::New("hello world"));

Apa? Anda bertanya kepada saya apakah itu?

Kemudian izinkan saya bercakap mengenainya sedikit, rujuk di sini dan dokumen rujukan V8.

Seperti yang ditunjukkan dalam dokumentasi, Local sebenarnya mewarisi daripada Handle Saya masih ingat bahawa Handle

Kemudian mari bercakap tentang Tempatan.


Terdapat dua jenis Handle, Local Handle dan Persistent Handle, masing-masing ialah Handle dan Persistent Kitaran hayat berada dalam skop. Kitaran hayat yang terakhir adalah di luar skop, dan anda perlu memanggil Persistent::Dispose secara manual untuk menamatkan kitaran hayatnya. Dalam erti kata lain, Local Handle adalah bersamaan dengan C `memperuntukkan objek pada timbunan dan Persistent Handle adalah bersamaan dengan C memperuntukkan objek pada timbunan.

Kemudian anda perlu mempunyai siri jadual parameter

Bagaimana untuk mendapatkan parameter baris arahan selepas memanggil C/C dari baris arahan terminal?

Salin kod Kod adalah seperti berikut:

#include

void main(int argc, char* argv[])
{
// ...
}

By the way, argc di sini ialah bilangan parameter baris arahan dan argv[] ialah setiap parameter. Kemudian memanggil fungsi panggil balik Node.js, v8 juga menggunakan kaedah yang serupa:

Salin kod Kod adalah seperti berikut:
V8EXPORT Local v8::Fungsi::Panggil(Handle< Objek>recv ,
int argc,
Mengendalikan argv[]
);

~~QAQ tersekat dalam Handle ! ! Akan sambung menulis esok. ~~

Nah, hari baru telah bermula dan saya berasa penuh kekuatan. (∩^o^)⊃━☆゚.*・。

Selepas saya mengesahkannya dalam banyak aspek (SegmentFault, StackOverflow dan kumpulan KouKou), saya akhirnya menyelesaikan maksud tiga parameter fungsi di atas.

Saya tidak akan bercakap banyak tentang dua parameter seterusnya Satu ialah bilangan parameter, dan satu lagi ialah susunan parameter. Bagi parameter pertama Handle recv, penjelasan StackOverflow ialah:


Ia adalah sama seperti memohon dalam JS, anda lakukan

Salin kod Kod adalah seperti berikut:

konteks var = ...;
cb.apply(konteks, [ ...args...]);

Objek diluluskan sebagai hujah pertama menjadi ini dalam skop fungsi Lebih banyak dokumentasi pada MDN Jika anda tidak mengetahui JS dengan baik, anda boleh membaca lebih lanjut tentang JS ini di sini: http://unschooled.org. /2012/03/understanding-javascript-this/

——Dipetik daripada StackOverflow

Ringkasnya, fungsinya adalah untuk menentukan penunjuk ini bagi fungsi yang dipanggil. Penggunaan Panggilan ini serupa dengan bind(), call(), dan apply() dalam JavaScript.

Jadi apa yang perlu kita lakukan ialah membina jadual parameter dahulu, dan kemudian masukkan fungsi Panggilan untuk pelaksanaan.

Langkah pertama ialah memaparkan fungsi penukaran, kerana ia pada asalnya jenis Objek:
Setempat cb = Setempat::Cast(args[0]);

Langkah kedua ialah mencipta jadual parameter (tatasusunan):
Setempat argv[argc] = { Setempat::Baru(String::Baru("hello world")) };

Siri fungsi panggilan terakhir

Panggil cb dan hantar parameter dalam:
cb->Panggil(Konteks::GetCurrent()->Global(), 1, argv);

Parameter pertama di sini, Context::GetCurrent()->Global(), bermakna mendapatkan konteks global seperti ini bagi fungsi ini; parameter kedua ialah nombor dalam jadual parameter (walaupun Node.js Tatasusunan mempunyai atribut panjang, tetapi sistem sebenarnya tidak mengetahui panjang tatasusunan dalam C, dan anda perlu memasukkan nombor sendiri untuk menunjukkan panjang tatasusunan yang terakhir ialah jadual parameter yang baru kami buat .

Siri Dokumen Akhir Bab Akhir

Saya percaya semua orang sudah biasa dengan langkah ini, iaitu menulis fungsi, kemudian memasukkannya ke dalam fungsi yang dieksport, dan akhirnya mengisytiharkannya.

Saya hanya akan melepaskan kod terus, atau anda boleh pergi terus ke dokumentasi Node.js.

Salin kod Kod adalah seperti berikut:

#include
menggunakan ruang nama v8;

Kendalikan RunCallback(Const Arguments& args)
{
Skop HandleScope;
Setempat cb = Setempat::Cast(args[0]);
const unsigned argc = 1;
Setempat argv[argc] = { Setempat::Baru(String::Baru("hello world")) };
cb->Panggil(Konteks::GetCurrent()->Global(), argc, argv);

kembalikan skop. Tutup(Tidak Ditakrifkan());
}

batal Init(Mengendalikan eksport, Modul Mengendalikan)
{
Modul->Set(String::NewSymbol("eksport"),
FunctionTemplate::New(RunCallback)->GetFunction());
}

MODUL_NODE(tambahan, Init)

Syabas! Lakukan sendiri langkah terakhir yang tinggal. Bagi memanggil fungsi ini dalam JS, saya telah menyebutnya sebelum ini.

Tambahan

Yalah, saya rasa nota belajar saya semakin tidak terkawal~

Mari berhenti di sini hari ini Dalam proses menulis nota kajian, saya menghadapi masalah lagi, seperti maksud parameter fungsi Panggilan.

Jika anda rasa siri nota pembelajaran ini masih membantu anda, datang dan sertai saya dalam keseronokan~Σ>―(〃°ω°〃)♡→

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn