از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
روش ایجاد افزونه های C/C++ در NodeNode.js به دلایل زیادی عالی است، یکی از آنها سرعت ساخت برنامه های کاربردی معنی دار است. با این حال، همانطور که همه ما می دانیم، این به قیمت عملکرد (در مقایسه با کد بومی) است. برای دور زدن این موضوع، می توانید کد خود را در رابط بنویسید…
سرفصلهای مطلب
Node.js به دلایل زیادی عالی است، یکی از آنها سرعتی است که در آن می توانید برنامه های کاربردی معنادار بسازید. با این حال، همانطور که همه ما می دانیم، این به قیمت عملکرد (در مقایسه با کد بومی) است. برای دور زدن این موضوع، میتوانید کد خود را بنویسید تا با کدهای سریعتر نوشته شده در C یا C++ رابط کاربری داشته باشید. تنها کاری که باید انجام دهیم این است که به Node اطلاع دهیم که این کد را کجا پیدا کند و چگونه با آن ارتباط برقرار کند.
بسته به چند راه برای حل این مشکل وجود دارد روی چه سطحی از انتزاع را می خواهید ما با کمترین انتزاع که Node است شروع می کنیم اضافه کردن-روی.
افزونه ها
یک افزودنی-روی با ارائه چسب بین کتابخانه های Node و C/C++ کار می کند. برای توسعهدهنده Node معمولی، این ممکن است کمی پیچیده باشد، زیرا برای تنظیم رابط باید وارد نوشتن کد C/C++ شوید. با این حال، بین این مقاله و مستندات Node، باید بتوانید چند رابط ساده کار کنید.
قبل از اینکه بتوانیم به ایجاد افزونهها بپردازیم، باید چند چیز را مرور کنیم. اول از همه، ما باید بدانیم که چگونه کد بومی را کامپایل کنیم (چیزی که توسعه دهندگان Node با خوشحالی فراموشش می کنند). این کار با استفاده از node-گیپ. سپس به طور خلاصه در مورد آن صحبت خواهیم کرد نان، که به مدیریت نسخه های مختلف Node API کمک می کند.
node-گیپ
انواع مختلفی از پردازندهها (x86، ARM، PowerPC و غیره) و حتی سیستمعاملهای بیشتری برای کامپایل کردن کد شما وجود دارد. خوشبختانه، node-gyp
همه اینها را برای شما مدیریت می کند. همانطور که توسط GitHub آنها توضیح داده شده است page، node-gyp
یک “کراس پلتفرم” است command-line ابزار نوشته شده در Node.js برای کامپایل افزونه بومیon ماژول ها برای Node.js”. اساسا، node-gyp
فقط یک لفاف در اطراف است جیپ، که توسط تیم Chromium ساخته شده است.
README پروژه دستورالعمل های خوبی دارد روی روش نصب و استفاده از بسته، بنابراین برای جزئیات بیشتر باید آن را بخوانید. به طور خلاصه، برای استفاده node-gyp
باید موارد زیر را انجام دهید
به دایرکتوری پروژه خود بروید:
$ cd my_node_addon
فایل های ساخت مناسب را با استفاده از configure
دستور، که یکی را ایجاد می کند Makefile
(روی یونیکس)، یا vcxproj
(روی پنجره ها):
$ node-gyp configure
و در نهایت پروژه را بسازید:
$ node-gyp build
این یک را ایجاد می کند /build
دایرکتوری شامل، در میان چیزهای دیگر، باینری کامپایل شده است.
حتی زمانی که از انتزاعات بالاتری مانند ffi
بسته، هنوز هم خوب است که بفهمیم در زیر کاپوت چه اتفاقی میافتد، بنابراین توصیه میکنم برای یادگیری نکات زیر وقت بگذارید. node-gyp
.
نان
nan
(Native Abstractions for Node) یک ماژول است که به راحتی نادیده گرفته می شود، اما ساعت ها شما را از ناامیدی نجات می دهد. بین نسخه های Node v0.8
، v0.10
، و v0.12
، نسخه های V8 مورد استفاده تغییرات بزرگی را تجربه کردند (علاوه بر تغییرات در خود Node). nan
کمک می کند تا این تغییرات را از شما پنهان کنید و یک رابط خوب و سازگار ارائه می دهد.
این انتزاع بومی با ارائه اشیا/توابع C/C++ در آن کار میکند #include <nan.h>
فایل هدر
برای استفاده از آن، نصب کنید nan
بسته:
$ npm install --save nan
این خطوط را به خود اضافه کنید binding.gyp
فایل:
"include_dirs" : (
"<!(node -e \"require('nan')\")"
)
و شما آماده استفاده از آن هستید روش ها / توابع از جانب nan.h
به جای قلاب اصلی #include <node.h>
کد من به شدت توصیه می کنم استفاده کنید nan
. در این مورد اختراع مجدد چرخ فایده ای ندارد.
ایجاد Add-روی
قبل از شروع روی افزودنی شما-روی، مطمئن شوید که برای آشنایی با کتابخانه های زیر کمی وقت گذاشته اید:
- کتابخانه V8 JavaScript C++، که برای رابط واقعی با جاوا اسکریپت (مانند ایجاد توابع، فراخوانی اشیا و غیره) استفاده می شود.
- توجه داشته باشید:
node.h
فایل پیش فرض پیشنهاد شده است، اما واقعاnan.h
باید به جای آن استفاده شود
- توجه داشته باشید:
- لیبوویک کتابخانه ورودی/خروجی ناهمزمان بین پلتفرمی که به زبان C نوشته شده است. این کتابخانه برای انجام هر نوع ورودی/خروجی (باز کردن فایل، نوشتن در شبکه، تنظیم تایمر و غیره) در کتابخانه های بومی شما مفید است. تا آن را ناهمزمان کند.
- کتابخانه های گره داخلی یکی از موضوعات مهم برای درک این است
node::ObjectWrap
، که اکثر اشیا از آن مشتق شده اند.
در طول بقیه این بخش، من شما را از طریق یک مثال واقعی راهنمایی می کنم. در این مورد، ما یک را ایجاد خواهیم کرد hook به C++ <cmath>
کتابخانه pow
تابع. از آنجایی که تقریباً همیشه باید از آن استفاده کنید nan
، این چیزی است که من در طول مثال ها استفاده خواهم کرد.
برای این مثال، در add-روی پروژه شما باید حداقل این فایل ها را در اختیار داشته باشید:
pow.cpp
binding.gyp
package.json
فایل C++ نیازی به نامگذاری ندارد pow.cpp
، اما نام معمولاً نشان دهنده این است که یک افزودنی استon، یا عملکرد خاص آن.
// pow.cpp
#include <cmath>
#include <nan.h>
void Pow(const Nan::FunctionCallbackInfo<v8::Value>& info) {
if (info.Length() < 2) {
Nan::ThrowTypeError("Wrong number of arguments");
return;
}
if (!info(0)->IsNumber() || !info(1)->IsNumber()) {
Nan::ThrowTypeError("Both arguments should be numbers");
return;
}
double arg0 = info(0)->NumberValue();
double arg1 = info(1)->NumberValue();
v8::Local<v8::Number> num = Nan::New(pow(arg0, arg1));
info.GetReturnValue().Set(num);
}
void Init(v8::Local<v8::Object> exports) {
exports->Set(Nan::New("pow").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(Pow)->GetFunction());
}
NODE_MODULE(pow, Init)
توجه داشته باشید که نقطه ویرگول وجود ندارد (;
) در پایان NODE_MODULE
. از آنجایی که این کار به عمد انجام می شود NODE_MODULE
در واقع یک تابع نیست – یک ماکرو است.
کد بالا ممکن است در ابتدا کمی دلهره آور به نظر برسد برای کسانی که مدتی است (یا هرگز هرگز C++) ننوشته اند، اما درک آن واقعاً چندان سخت نیست. را Pow
تابع همان کدی است که در آن تعداد آرگومان های ارسال شده، انواع آرگومان ها را بررسی می کنیم، بومی را فراخوانی می کنیم. pow
تابع، و نتیجه را به برنامه Node برگردانید. را info
شی شامل همه چیزهایی در مورد فراخوانی است که باید بدانیم، از جمله آرگومان ها (و انواع آنها) و مکانی برای برگرداندن نتیجه.
را Init
تابع بیشتر فقط مربوط به Pow
عملکرد با
“pow” نام، و NODE_MODULE
ماکرو در واقع ثبت افزودنی را انجام می دهدon با Node.
را package.json
فایل تفاوت زیادی با یک ماژول Node معمولی ندارد. اگرچه به نظر نمی رسد نیازی به آن باشد، اما بیشتر Add-روی ماژول ها دارند "gypfile": true
مجموعه در داخل آنها، اما ساخت process به نظر می رسد هنوز بدون آن خوب کار می کند. در اینجا چیزی است که من برای این مثال استفاده کردم:
{
"name": "addon-hook",
"version": "0.0.0",
"description": "Node.js Add-روی Example",
"main": "index.js",
"dependencies": {
"nan": "^2.0.0"
},
"scripts": {
"test": "node index.js"
}
}
در مرحله بعد، این کد باید در a ساخته شود pow.node
فایل که باینری Add- استon. برای انجام این کار، باید بگویید node-gyp
چه فایل هایی برای کامپایل نیاز دارد و نام فایل حاصل باینری. در حالی که بسیاری از گزینه ها/پیکربندی های دیگر وجود دارد که می توانید از آنها استفاده کنید node-gyp
، برای این مثال به مقدار زیادی نیاز نداریم. را binding.gyp
فایل می تواند به سادگی باشد:
{
"targets": (
{
"target_name": "pow",
"sources": ( "pow.cpp" ),
"include_dirs": (
"<!(node -e \"require('nan')\")"
)
}
)
}
در حال حاضر، با استفاده از node-gyp
، فایل های ساخت پروژه مناسب را برای پلتفرم داده شده ایجاد کنید:
$ node-gyp configure
و در نهایت پروژه را بسازید:
$ node-gyp build
این باید منجر به الف شود pow.node
فایل در حال ایجاد است که در build/Release/
فهرست راهنما. برای استفاده از این hook در کد برنامه شما، فقط require
در pow.node
فایل (بدون .node
افزونه):
var addon = require('./build/Release/pow');
console.log(addon.pow(4, 2)); // Prints '16'
رابط عملکرد خارجی گره
توجه داشته باشید: ffi
بسته قبلاً به عنوان شناخته شده است node-ffi
. جدیدتر را حتما اضافه کنید ffi
وابستگی های خود را نام ببرید تا از سردرگمی زیادی در طول آن جلوگیری کنید npm install
🙂
در حالی که افزودن-روی عملکرد ارائه شده توسط Node تمام انعطافپذیری مورد نیاز را به شما میدهد، همه توسعهدهندگان/پروژهها به آن نیاز ندارند. در بسیاری از موارد انتزاعی مانند ffi
به خوبی انجام می شود و معمولاً به برنامه نویسی C/C++ بسیار کم یا بدون نیاز است.
ffi
فقط کتابخانههای پویا را بارگیری میکند، که میتواند برای برخی محدود باشد، اما راهاندازی قلابها را نیز بسیار آسانتر میکند.
var ffi = require('ffi');
var libm = ffi.Library('libm', {
'pow': ( 'double', ( 'double', 'double' ) )
});
console.log(libm.pow(4, 2)); // 16
کد بالا با تعیین کتابخانه برای بارگذاری کار می کند (libm
و به طور خاص چه روش هایی را از آن کتابخانه بارگیری کنیم (pow). را ( 'double', ( 'double', 'double' ) )
خط می گوید ffi
نوع برگشتی و پارامترهای متد چیست که در این حالت دو است double
پارامترها و الف double
بازگشت.
نتیجه
اگرچه ممکن است در ابتدا ترسناک به نظر برسد، ایجاد یک Add-روی واقعاً خیلی بد نیست بعد از اینکه شما این شانس را داشتید که با مثال کوچکی مانند این کار کنید روی مال خودت در صورت امکان، پیشنهاد میکنم به یک کتابخانه پویا متصل شوید تا ایجاد رابط و بارگذاری کد بسیار آسانتر شود، اگرچه برای بسیاری از پروژهها ممکن است این امکان پذیر نباشد یا بهترین انتخاب باشد.
آیا نمونهای از کتابخانهها وجود دارد که بخواهید صحافی برای آنها ببینید؟ در نظرات به ما اطلاع دهید!
(برچسبها برای ترجمه)# روش
منتشر شده در 1403-01-30 05:31:04