Revisi yang lama dan pelajari yang baru, Anda bisa menjadi basah
Pertama -tama, harap ingat manual online V8 ini - http://izs.me/v8-docs/main.html.
Ingat file building.gyp terakhir?
Salinan kode adalah sebagai berikut:
{
"Target": [
{
"target_name": "addon",
"Sumber": ["addon.cc"]
}
]
}
Sama seperti ini, belajar dari satu contoh dan belajar darinya. Jika Anda memiliki lebih banyak file *.cc, itu akan seperti ini:
"Sumber": ["addon.cc", "myexample.cc"]
Terakhir kali kami memisahkan dua langkah, dan pada kenyataannya, konfigurasi dan kompilasi dapat disatukan:
$ node-gyp konfigurasi build
Apakah Anda sudah selesai meninjau? tanpa? Lai
Oke, mari kita lanjutkan.
Daftar isi
Parameter fungsi
Sekarang kita akhirnya akan berbicara tentang parameter.
Mari kita bayangkan ada fungsi add (a, b) yang mewakili menambahkan A dan B untuk mengembalikan hasilnya, jadi tulis fungsi bingkai luar terlebih dahulu:
Salinan kode adalah sebagai berikut:
#include <node.h>
menggunakan namespace v8;
Tangani <value> Tambah (Const Arguments & Args)
{
Ruang lingkup pegangan;
// ... Datang lagi!
}
Argumen
Ini adalah parameter fungsi. Mari kita lihat referensi manual resmi V8 terlebih dahulu.
• int panjang () const
• Operator <value> lokal [] (int i) const
Kami tidak peduli dengan yang lain, keduanya sangat penting! Satu mewakili jumlah parameter yang dilewati dalam fungsi, dan yang lainnya adalah tanda kurung yang mengakses parameter ke -n melalui indeks subskrip.
Jadi untuk persyaratan di atas, kita dapat secara kasar memahami bahwa args.length () adalah 2, Args [0] mewakili A dan ARGS [1] mewakili b. Dan kita harus menilai bahwa jenis kedua angka ini harus nomor.
Tidak yakin, operator indeks dalam braket mengembalikan hasil <value> lokal, yang merupakan kelas dasar dari semua jenis node.js. Oleh karena itu, jika parameter yang dilewati adalah dari berbagai jenis, kita harus menilai parameter apa itu. Ini terkait dengan beberapa fungsi jenis nilai ini.
• isArray ()
• Isboolean ()
• isDate ()
• isfunction ()
• isInt32 ()
• isnativeError ()
• isnull ()
• isNumber ()
• isRegExp ()
• isstring ()
• ...
Saya tidak akan mencantumkan semuanya, membaca sisanya sendiri. 。 :. ゚ (*´∀`) ノ゚ .:。
ThrowException
Ini adalah fungsi yang akan kita gunakan nanti. Secara khusus, dapat ditemukan dalam dokumentasi V8.
Seperti namanya, ia melempar kesalahan. Setelah menjalankan pernyataan ini, itu setara dengan menjalankan pernyataan Throw () dalam file node.js lokal. Misalnya:
ThrowException (Exception :: TypeError (String :: New ("Jumlah Argumen yang Salah")));
Itu setara dengan mengeksekusi node.js:
melempar typeError baru ("jumlah argumen yang salah");
Belum diartikan()
Fungsi ini juga ada dalam dokumen.
Secara khusus, ini adalah nilai nol, karena beberapa fungsi tidak perlu mengembalikan nilai spesifik apa pun, atau tidak mengembalikan nilai. Pada saat ini, tidak terdefinisi () perlu digunakan sebagai gantinya.
Ambil tindakan!
Setelah memahami poin -poin di atas, saya yakin Anda akan dapat menulis logika A + B segera. Saya akan menyalin kode manual resmi Node.js dan membacanya untuk Anda. Itu akan dilakukan:
Salinan kode adalah sebagai berikut:
#include <node.h>
menggunakan namespace v8;
Tangani <value> Tambah (Const Arguments & Args)
{
Ruang lingkup pegangan;
// itu berarti bahwa lebih dari 2 parameter dapat dilewati, tetapi pada kenyataannya kami hanya menggunakan dua yang pertama
if (args.length () <2)
{
// Lemparkan kesalahan
ThrowException (Exception :: TypeError (String :: New ("Jumlah Argumen yang Salah")));
// mengembalikan nilai kosong
return scope.close (tidak terdefinisi ());
}
// Jika salah satu dari dua parameter pertama bukanlah angka
if (! args [0]-> isNumber () ||! args [1]-> isNumber ())
{
// Lemparkan kesalahan dan kembalikan nilai nol
ThrowException (Exception :: typeError (String :: new ("Argumen yang salah"));
return scope.close (tidak terdefinisi ());
}
// Untuk detailnya, silakan merujuk ke dokumentasi V8
// http://izs.me/v8-docs/classv8_1_1value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// fungsi `numberValue`
Lokal <number> num = number :: new (args [0]-> numberValue () + args [1]-> numberValue ());
return scope.close (num);
}
Fungsinya selesai!
Akhirnya, tulis fungsi ekspor di akhir dan akan baik -baik saja.
Salinan kode adalah sebagai berikut:
void init (handle <bes Object> Ekspor)
{
ekspor-> set (string :: newsymbol ("add"),
FunctionTemplate :: new (add)-> getFunction ());
}
Node_module (addon, init)
Setelah Anda mengkompilasi, kami dapat menggunakannya seperti ini:
Salinan kode adalah sebagai berikut: var addon = membutuhkan ('./ Build/Release/Addon');
console.log (addon.add (1, 1) + "b");
Anda akan melihat 2B! ✧。٩ (ᗜ) و✧*.
Fungsi panggilan balik
Di bab sebelumnya, kami hanya berbicara tentang Hello World. Dalam bab ini, Guru Nenek menemukannya dengan hati nurani dan menulis fungsi panggilan balik.
Untuk konvensi, mari kita tulis kerangka kerja terlebih dahulu:
Salinan kode adalah sebagai berikut:
#include <node.h>
menggunakan namespace v8;
Tangani <value> Runceallback (Const Arguments & Args)
{
Ruang lingkup pegangan;
// ... crackle crackle crackle crackle crackle crackle crackle crackle crackle
return scope.close (tidak terdefinisi ());
}
Lalu kami memutuskan bagaimana ini digunakan seperti ini:
func (function (msg) {
console.log (msg);
});
Artinya, itu akan meneruskan parameter ke fungsi callback, kami membayangkan itu adalah string, dan kemudian kami dapat menghibur.log () untuk melihatnya.
Pertama, Anda membutuhkan serial string
Tanpa basa -basi lagi, mari kita beri makan string terlebih dahulu. (√ ζ ε :)
Tetapi kita harus membuat string tipe generik ini karena kode node.js lemah.
Lokal <value> :: new (string :: new ("hello world"));
Apa? Anda bertanya kepada saya apa itu <value> lokal?
Kemudian saya akan membicarakannya sedikit, merujuk ke dokumen referensi dari sini dan V8.
Seperti yang ditunjukkan oleh dokumentasi, lokal <T> sebenarnya mewarisi dari pegangan <T>, dan saya ingat bahwa bab sebelumnya sudah berbicara tentang Handle <T>.
Lalu inilah yang lokal.
Ada dua jenis pegangan, pegangan lokal, dan pegangan persisten, yang merupakan <T> lokal: pegangan <T> dan persisten <T>: Handle <T>. Tidak ada perbedaan antara yang pertama dan menangani <T> dan kedua siklus bertahan hidup berada dalam ruang lingkup. Siklus hidup yang terakhir dipisahkan dari ruang lingkup, Anda perlu secara manual menyebut persisten :: buang untuk mengakhiri siklus hidupnya. Dengan kata lain, pegangan lokal setara dengan mengalokasikan objek pada tumpukan pada C ++ `dan pegangan persisten setara dengan C ++ mengalokasikan objek pada heap.
Maka Anda memerlukan seri tabel parameter
Bagaimana cara mendapatkan parameter baris perintah setelah memanggil C/C ++ pada baris perintah terminal?
Salinan kode adalah sebagai berikut:
#include <stdio.h>
void main (int argc, char* argv [])
{
// ...
}
Ngomong -ngomong, argc di sini adalah jumlah parameter baris perintah, dan argv [] adalah berbagai parameter. Kemudian V8 juga menggunakan metode yang serupa untuk memanggil fungsi panggilan balik node.js:
Salinan kode adalah sebagai berikut: V8Export Local <Value> V8 :: Function :: Call (Handle <Peject> Recv,
int argc,
Menangani <value> argv []
);
~~ QAQ macet di Handle <Peject> RECV! Lai Lai Teruslah menulis besok. ~~
Nah, hari baru dimulai dan saya merasa seperti saya penuh dengan kekuatan. (∩^o^) ⊃━☆゚.*・。。
Setelah saya memverifikasi dalam banyak aspek (SegmentFault, StackoverFlow dan grup QQ), saya akhirnya memecahkan arti dari tiga parameter dari fungsi di atas.
Saya tidak akan berbicara tentang dua parameter terakhir, satu adalah jumlah parameter, dan yang lainnya adalah array parameter. Adapun parameter pertama Handle <Peject> RECV, Penjelasan StackOverflow Brother adalah sebagai berikut:
Itu sama seperti yang diterapkan dalam JS. Di JS, Anda melakukannya
Salinan kode adalah sebagai berikut:
var context = ...;
CB.Apply (konteks, [... args ...]);
Objek yang dilewati sebagai argumen pertama menjadi ini dalam lingkup fungsi. Lebih banyak dokumentasi tentang MDN. Jika Anda tidak mengenal JS dengan baik, Anda dapat membaca lebih lanjut tentang JS ini di sini: http://unschooled.org/2012/03/understanding-javascript-this/
- Dikutip dari stackoverflow
Singkatnya, fungsinya adalah untuk menentukan pointer ini ke fungsi yang dipanggil. Penggunaan panggilan ini mirip dengan Bind (), call (), dan apply () di JavaScript.
Jadi yang harus kita lakukan adalah membangun tabel parameter terlebih dahulu, dan kemudian lulus dalam fungsi panggilan ini untuk eksekusi.
Langkah pertama adalah menampilkan fungsi konversi, karena awalnya merupakan tipe objek:
Lokal <Function> CB = Lokal <Function> :: cast (args [0]);
Langkah kedua adalah membuat tabel parameter (array):
Lokal <value> argv [argc] = {Lokal <value> :: new (string :: new ("hello world"))};
Panggilan terakhir ke seri fungsi
Hubungi CB dan lewati parameter di:
CB-> Call (Context :: GetCurrent ()-> Global (), 1, argv);
Parameter pertama di sini konteks :: getCurrent ()-> global () berarti mendapatkan fungsi konteks global ini; Parameter kedua adalah angka dalam tabel parameter (setelah semua, meskipun array node.js memiliki atribut panjang, sistem sebenarnya tidak tahu panjang array dalam C ++, dan Anda harus lulus dalam angka untuk menjelaskan panjang array); Parameter terakhir adalah tabel parameter yang baru saja kami buat.
Seri File Akhir Bab Akhir
Saya percaya bahwa semua orang sudah terbiasa dengan langkah ini, cukup tuliskan fungsinya, lalu masukkan ke dalam fungsi ekspor, dan akhirnya nyatakan.
Saya hanya akan memposting kode, atau hanya pergi ke dokumen Node.js untuk membacanya.
Salinan kode adalah sebagai berikut:
#include <node.h>
menggunakan namespace v8;
Tangani <value> Runceallback (Const Arguments & Args)
{
Ruang lingkup pegangan;
Lokal <Function> CB = Lokal <Function> :: cast (args [0]);
const unsigned argc = 1;
Lokal <value> argv [argc] = {Lokal <value> :: new (string :: new ("hello world"))};
CB-> Call (Context :: GetCurrent ()-> Global (), argc, argv);
return scope.close (tidak terdefinisi ());
}
void init (handle <boject> Ekspor, Tangani Modul <Titik>)
{
modul-> set (string :: newsymbol ("Exports"),
FunctionTemplate :: new (runcallback)-> getFunction ());
}
Node_module (addon, init)
Bagus sekali! Ayo sendiri langkah terakhir. Adapun untuk memanggil fungsi ini di JS, saya telah menyebutkannya sebelumnya.
Tambahan
Yah, saya merasa bahwa catatan studi saya menjadi semakin tidak terkendali dan ingin memecahkannya ~
Mari kita berhenti di sini hari ini. Selama proses menulis catatan studi, saya telah meningkatkan postur tubuh saya lagi, seperti makna parameter dari fungsi panggilan.
Jika Anda pikir serangkaian catatan studi ini bermanfaat bagi Anda, datang dan bersenang -senang dengan saya ~ σ> (〃 ° ω ° 〃) ♡ →