ข้อผิดพลาดจาก N เมื่อนานมาแล้ว - การใช้ node.js เพื่อสร้างผู้พิพากษาออนไลน์ของ NBUT ใหม่รวมถึงด้านการประเมินผลก็ต้องมีการสร้างใหม่ (สำหรับเมื่อเสร็จแล้วอย่าสนใจ (/д ′)/~
ในระยะสั้นสิ่งที่เราจะทำตอนนี้คือการใช้ C/C ++ เพื่อใช้โมดูล Node.js
การตระเตรียม
หากคุณต้องการทำสิ่งต่าง ๆ ให้ดีคุณต้องทำตัวเหมือนนักเลงและทำให้เครื่องมือของคุณคมขึ้น
โหนด
ก่อนอื่นคุณต้องมีโมดูลโหนด GYP
ไม่ว่าในมุมใดก็ตามดำเนินการ:
การคัดลอกรหัสมีดังนี้:
$ npm ติดตั้ง node -gyp -g
หลังจากชุดของ blahblahs คุณได้ติดตั้งแล้ว
งูหลาม
จากนั้นคุณต้องมีสภาพแวดล้อม Python
ไปที่เว็บไซต์อย่างเป็นทางการและรับเว็บไซต์
หมายเหตุ: ตามจอแสดงผล GitHub ของ Node-Gyp ตรวจสอบให้แน่ใจว่าเวอร์ชัน Python ของคุณอยู่ระหว่าง 2.5.0 ถึง 3.0.0
สภาพแวดล้อมการรวบรวม
ฉันแค่ขี้เกียจและไม่เขียนอย่างละเอียด โปรดย้ายไปที่ Node-Gyp เพื่อดูความต้องการของคอมไพเลอร์ และทำให้เอะอะ
เริ่มต้น
ฉันจะบอกคุณเกี่ยวกับการแนะนำเว็บไซต์อย่างเป็นทางการสวัสดี World
สวัสดีโลก
โปรดเตรียมไฟล์ C ++ ตัวอย่างเช่นเรียกว่า ~~ sb.cc ~~ hello.cc
จากนั้นเราจะทำทีละขั้นตอนก่อนสร้างไฟล์ส่วนหัวและกำหนดเนมสเปซ:
การคัดลอกรหัสมีดังนี้:
#include <node.h>
#include <v8.h>
ใช้เนมสเปซ V8;
ฟังก์ชั่นหลัก
ต่อไปเราจะเขียนฟังก์ชั่นที่มีค่าส่งคืน <alde>
การคัดลอกรหัสมีดังนี้:
จัดการ <ค่า> สวัสดี (อาร์กิวเมนต์ const & args)
-
// ... หิวจะเขียน
-
จากนั้นฉันจะวิเคราะห์สิ่งเหล่านี้โดยประมาณ:
จัดการ <ค่า>
คุณต้องซื่อสัตย์ในชีวิต ฉันประกาศล่วงหน้าว่าฉันอ้างถึงจากที่นี่ (@Fool)
V8 ใช้ประเภทที่จับเพื่อโฮสต์วัตถุ JavaScript เช่นเดียวกับ STD :: SharedPointer ของ C ++ การกำหนดประเภทระหว่างการจัดการจะผ่านการอ้างอิงวัตถุโดยตรง แต่ความแตกต่างคือ V8 ใช้ GC ของตัวเองเพื่อจัดการวงจรชีวิตของวัตถุมากกว่าจำนวนการอ้างอิงที่ใช้กันทั่วไปโดยสมาร์ทพอยน์เตอร์
ประเภท JavaScript มีประเภทที่กำหนดเองที่สอดคล้องกันใน C ++ เช่นสตริง, จำนวนเต็ม, วัตถุ, วันที่, อาร์เรย์ ฯลฯ และปฏิบัติตามความสัมพันธ์การสืบทอดใน JavaScript อย่างเคร่งครัด เมื่อใช้ประเภทเหล่านี้ใน C ++ คุณต้องใช้ Handle Hosting เพื่อใช้ GC เพื่อจัดการวงจรชีวิตของพวกเขาโดยไม่ต้องใช้สแต็คดั้งเดิมและกอง
ค่าที่เรียกว่านี้ซึ่งสามารถมองเห็นได้จากความสัมพันธ์การสืบทอดต่าง ๆ ในไฟล์ส่วนหัว V8.h ของเครื่องยนต์ V8 จริง ๆ แล้วเป็นคลาสพื้นฐานของวัตถุต่าง ๆ ใน JavaScript
หลังจากทำความเข้าใจกับสิ่งนี้เราสามารถเข้าใจความหมายของคำสั่งฟังก์ชั่นข้างต้นอย่างคร่าวๆซึ่งหมายความว่าเราเขียนฟังก์ชั่นสวัสดีซึ่งส่งคืนค่าประเภทที่ไม่แน่นอน
หมายเหตุ: เราสามารถส่งคืนประเภทเฉพาะ ได้แก่ สตริงจำนวนเต็ม ฯลฯ ภายใต้การจัดการโฮสติ้ง
ข้อโต้แย้ง
นี่คือพารามิเตอร์ที่จะผ่านในฟังก์ชั่นนี้ เราทุกคนรู้ว่าใน node.js จำนวนพารามิเตอร์เป็นแบบสุ่ม เมื่อพารามิเตอร์เหล่านี้ถูกส่งไปยัง C ++ พวกเขาจะถูกแปลงเป็นวัตถุประเภทอาร์กิวเมนต์
มาพูดคุยเกี่ยวกับการใช้งานเฉพาะในภายหลัง ที่นี่เราแค่ต้องเข้าใจว่านี่คืออะไร (เพื่อให้เป็นความลับหรือไม่เพราะตัวอย่างในเอกสารอย่างเป็นทางการของ Node.js ถูกกล่าวถึงแยกต่างหากฉันแค่พูดถึงตัวอย่าง Hello World ครั้งแรก (´థ౪థ) σ
เพิ่มอิฐและกระเบื้อง
ต่อไปเราเริ่มมีส่วนร่วม เพียงแค่ประโยคที่ง่ายที่สุด:
การคัดลอกรหัสมีดังนี้:
จัดการ <ค่า> สวัสดี (อาร์กิวเมนต์ const & args)
-
ขอบเขตของ Handlescope;
return scope.close (string :: new ("โลก"));
-
สองประโยคนี้หมายถึงอะไร? ความหมายทั่วไปคือการส่งคืนสตริง "โลก" ใน Node.js
ผู้ดูแล
ข้อมูลอ้างอิงเดียวกันมาจากที่นี่
วงจรชีวิตของการจัดการนั้นแตกต่างจากตัวชี้อัจฉริยะ C ++ มันไม่ได้อยู่รอดภายในขอบเขตของความหมาย C ++ (นั่นคือส่วนที่ล้อมรอบด้วย {}) แต่จำเป็นต้องระบุด้วยตนเองผ่าน Handlescope Handlescope สามารถจัดสรรได้บนสแต็กเท่านั้น หลังจากประกาศวัตถุ Handlescope แล้วมือจับที่สร้างขึ้นในภายหลังจะได้รับการจัดการโดย Handlescope หลังจากวัตถุ Handlescope ถูกทำลายการจัดการที่จัดการโดย GC จะถูกกำหนด
ดังนั้นเราต้องประกาศขอบเขตนี้เมื่อเราต้องการจัดการวงจรชีวิต ตกลงทำไมรหัสของเราไม่เขียนแบบนี้?
การคัดลอกรหัสมีดังนี้:
จัดการ <ค่า> สวัสดี (อาร์กิวเมนต์ const & args)
-
ขอบเขตของ Handlescope;
return String :: ใหม่ ("โลก");
-
เพราะเมื่อฟังก์ชั่นกลับมาขอบเขตจะถูกทำลายและการจัดการที่จัดการจะถูกรีไซเคิลดังนั้นสตริงนี้จะไม่มีความหมาย
ดังนั้น V8 จึงเกิดความคิดที่วิเศษ - ฟังก์ชั่น Handlescope :: Close (Handle <t> value)! จุดประสงค์ของฟังก์ชั่นนี้คือการปิดขอบเขตและส่งพารามิเตอร์ภายในการจัดการขอบเขตก่อนหน้านั่นคือขอบเขตก่อนเข้าสู่ฟังก์ชั่นนี้
ดังนั้นเราจึงมีรหัสรหัสก่อนหน้านี้ cope.close (String :: new ("โลก"));
สตริง :: ใหม่
คลาสสตริงสอดคล้องกับคลาสสตริงดั้งเดิมใน node.js สืบทอดมาจากคลาสค่า ในทำนองเดียวกันมี:
•อาร์เรย์
•จำนวนเต็ม
•บูลีน
•วัตถุ
•วันที่
•ตัวเลข
•การทำงาน
-
บางสิ่งเหล่านี้ได้รับการสืบทอดมาจากคุณค่าในขณะที่บางอย่างได้รับการสืบทอดมาจากรอง เราจะไม่ทำวิจัยมากที่นี่ คุณสามารถดูรหัส V8 (อย่างน้อยไฟล์ส่วนหัว) หรือดูคู่มือนี้
แล้วสิ่งใหม่นี้ล่ะ? คุณสามารถดูได้ที่นี่ มันคือการสร้างวัตถุสตริงใหม่
ณ จุดนี้เราได้แยกวิเคราะห์ฟังก์ชั่นหลักนี้เสร็จแล้ว
วัตถุส่งออก
มาตรวจสอบกันเถอะ หากเขียนไว้ใน node.js เราจะส่งออกฟังก์ชั่นหรือวัตถุได้อย่างไร
การคัดลอกรหัสมีดังนี้:
exports.hello = function () {}
ดังนั้นเราจะทำสิ่งนี้ใน C ++ ได้อย่างไร?
เริ่มต้นฟังก์ชั่น
ก่อนอื่นมาเขียนฟังก์ชั่นการเริ่มต้น:
การคัดลอกรหัสมีดังนี้:
เป็นโมฆะ init (handle <jobick> การส่งออก)
-
// ... ฉันหิวที่จะเขียนเกี่ยวกับน้องสาวของคุณ! #゚ Å゚) ⊂ち☆)) ゚ д ゚) ・∵
-
นี่คือตูดเต่า! ไม่สำคัญว่าชื่อฟังก์ชั่นหรือบางสิ่งบางอย่าง แต่พารามิเตอร์ที่ผ่านจะต้องเป็นที่จับ <jobch> ซึ่งหมายความว่าเราจะส่งออกสิ่งต่าง ๆ จากผลิตภัณฑ์นี้ด้านล่าง
จากนั้นเราเขียนสิ่งที่ส่งออกที่นี่:
การคัดลอกรหัสมีดังนี้:
เป็นโมฆะ init (handle <jobick> การส่งออก)
-
Exports-> set (string :: newsymbol ("สวัสดี")
functionTemplate :: ใหม่ (สวัสดี)-> getFunction ());
-
ความหมายทั่วไปคือการเพิ่มฟิลด์ที่เรียกว่า Hello ไปยังวัตถุการส่งออกนี้และสิ่งที่เกี่ยวข้องคือฟังก์ชั่นและฟังก์ชั่นนี้เป็นฟังก์ชั่นสวัสดีที่รักของเรา
เพื่อเขียนจุดง่าย ๆ ในรหัสหลอก:
การคัดลอกรหัสมีดังนี้:
เป็นโมฆะ init (handle <jobick> การส่งออก)
-
exports.set ("สวัสดี", ฟังก์ชั่นสวัสดี);
-
งานเสร็จแล้ว!
(น้องสาวของคุณเสร็จแล้วหุบปาก ('д'⊂☡☆)) д)
การส่งออกที่แท้จริง
นี่เป็นขั้นตอนสุดท้ายและในที่สุดเราก็จะประกาศว่านี่คือทางเข้าสู่การส่งออกดังนั้นเราจึงเพิ่มบรรทัดนี้ในตอนท้ายของรหัส:
node_module (สวัสดี, init)
คุณเคยใช้ NI หรือไม่? - นี่คืออะไร?
ไม่ต้องกังวล node_module นี้เป็นแมโครซึ่งหมายความว่าเราใช้ฟังก์ชั่นการเริ่มต้นเริ่มต้นเพื่อส่งออกสิ่งที่จะส่งออกไปยัง Hello แล้วสวัสดีนี่มาจากไหน?
มันมาจากชื่อไฟล์! ใช่มันมาจากชื่อไฟล์ คุณไม่จำเป็นต้องประกาศล่วงหน้าและคุณไม่ต้องกังวลว่าจะไม่สามารถใช้งานได้ ในระยะสั้นชื่อไฟล์ไบนารีที่รวบรวมสุดท้ายของคุณคืออะไร? คุณจะกรอกข้อมูลในสวัสดีที่นี่และแน่นอนคุณต้องลบชื่อต่อท้าย
ดูเอกสารอย่างเป็นทางการสำหรับรายละเอียด
โปรดทราบว่าโหนดทั้งหมดเพิ่มจะต้องส่งออกฟังก์ชั่นการเริ่มต้น:
การคัดลอกรหัสมีดังนี้:
เป็นโมฆะเริ่มต้น (ด้ามจับ <Ojrop> การส่งออก);
node_module (module_name, เริ่มต้น)
ไม่มีกึ่งอวโลนหลังจาก node_module เนื่องจากไม่ใช่ฟังก์ชั่น (ดู node.h)
module_name จำเป็นต้องจับคู่ชื่อไฟล์ของไบนารีสุดท้าย (ลบคำต่อท้าย. node)
คอมไพล์ (๑ • ́ • ̀๑)
มาคอมไพล์กันเถอะ!
มาสร้างไฟล์เก็บถาวรใหม่ที่คล้ายกับ MakeFile - binding.gyp
และเพิ่มรหัสเช่นนี้:
การคัดลอกรหัสมีดังนี้:
-
"เป้าหมาย": [
-
"target_name": "สวัสดี",
"แหล่งที่มา": ["hello.cc"]
-
-
-
ทำไมต้องเขียนสิ่งนี้? คุณสามารถอ้างถึงเอกสารอย่างเป็นทางการของ Node-Gyp
กำหนดค่า
หลังจากไฟล์พร้อมแล้วเราต้องดำเนินการคำสั่งนี้ในไดเรกทอรีนี้:
การคัดลอกรหัสมีดังนี้:
$ node-gyp กำหนดค่า
หากทุกอย่างเรียบร้อยควรสร้างไดเรกทอรีบิลด์และจากนั้นก็มีไฟล์ที่เกี่ยวข้องภายในอาจมีไฟล์ M $ Visual Studio VCXPROJ ฯลฯ หรืออาจ MakeFile ขึ้นอยู่กับแพลตฟอร์ม
สร้าง
หลังจากสร้าง makefile เราเริ่มสร้างและรวบรวม:
$ node-gyp build
เฉพาะเมื่อทุกอย่างถูกรวบรวมจะได้รับการพิจารณาว่างานจริงเสร็จสมบูรณ์! หากคุณไม่เชื่อให้ไปตรวจสอบไดเรกทอรี Build/Release มีไฟล์ hello.node ด้านล่างหรือไม่? ถูกต้องนี่คือสบู่ที่ C ++ ต้องการรับสำหรับ node.js ในภายหลัง!
มารับพื้นฐานกันเถอะ! โหนด (✿゚゚) ノ C ++
เราสร้างไฟล์ใหม่ jianfeizao.js ในไดเรกทอรีตอนนี้:
การคัดลอกรหัสมีดังนี้:
var addon = ต้องการ ("./ build/release/hello");
console.log (addon.hello ());
ดูหรือไม่! ดูหรือไม่! ออกมา ผลลัพธ์ของ node.js และ c ++ รับพื้นฐาน! addon.hello () นี้เป็นที่จับ <ald> hello (const อาร์กิวเมนต์ & args) ที่เราเขียนในรหัส C ++ ก่อนหน้านี้และตอนนี้เราได้ส่งออกค่าที่ส่งคืน
อาบน้ำและเข้านอนและส่วนถัดไปจะลึกกว่า
มันมาสายแล้วฉันจะจบลงด้วยการเขียนวันนี้ จนถึงตอนนี้ทุกคนสามารถมาพร้อมกับส่วนขยาย Hello World C ++ ขั้นพื้นฐานที่สุด ครั้งต่อไปที่ฉันเขียนฉันไม่รู้ว่าจะเป็นครั้งต่อไป
(เฮ้เฮ้อาจารย์จะไม่รับผิดชอบได้อย่างไร! (o ゚ロ?) ┌┛σ (ノ´ω`) ノ