Node.js C++ Embedder API: اجرای جاوااسکریپت از نرم‌افزارهای C++

Node.js مجموعه‌ای از APIهای C++ ارائه می‌دهد که به توسعه‌دهندگان اجازه می‌دهد جاوااسکریپت را در محیط Node.js از نرم‌افزارهای C++ اجرا کنند. این قابلیت برای سناریوهایی طراحی شده که Node.js به‌عنوان یک کتابخانه درون برنامهٔ C++ جاسازی می‌شود. برخلاف کدی که مستقیماً توسط Node.js اجرا می‌شود، استفاده از Node.js به‌عنوان کتابخانه ممکن است تغییرات ناسازگار در نسخه‌های اصلی داشته باشد.

C++ Embedder APInode::InitializeOncePerProcessMultiIsolatePlatformCommonEnvironmentSetupnode::Environment

~2 دقیقه مطالعه • بروزرسانی ۵ دی ۱۴۰۴

1. مقدمه


C++ Embedder API به توسعه‌دهندگان اجازه می‌دهد جاوااسکریپت را درون نرم‌افزارهای C++ اجرا کنند. این APIها در فایل src/node.h موجود هستند و برخی مفاهیم موردنیاز از V8 Embedder API گرفته می‌شوند.

2. راه‌اندازی وضعیت سراسری (Per-Process State)


  • پارامترهای CLI Node.js باید پردازش شوند.
  • نیازهای V8 مانند ایجاد یک v8::Platform باید فراهم شوند.
  • node::InitializeOncePerProcess برای مقداردهی اولیهٔ Node.js استفاده می‌شود.
  • MultiIsolatePlatform::Create() یک پلتفرم V8 ایجاد می‌کند که از Workerها پشتیبانی می‌کند.
int main(int argc, char** argv) {
  argv = uv_setup_args(argc, argv);
  std::vector args(argv, argv + argc);

  auto result = node::InitializeOncePerProcess(args, {...});
  if (result->early_return() != 0) return result->exit_code();

  auto platform = MultiIsolatePlatform::Create(4);
  V8::InitializePlatform(platform.get());
  V8::Initialize();

  int ret = RunNodeInstance(platform.get(), result->args(), result->exec_args());

  V8::Dispose();
  V8::DisposePlatform();
  node::TearDownOncePerProcess();
  return ret;
}

3. راه‌اندازی وضعیت هر نمونه (Per-Instance State)


  • هر node::Environment با یک v8::Isolate و یک uv_loop_t مرتبط است.
  • یک ArrayBuffer::Allocator باید فراهم شود (ترجیحاً از Node.js).
  • node::NewIsolate() یک Isolate جدید با hookهای Node.js ایجاد می‌کند.

4. اجرای کد جاوااسکریپت


  • node::LoadEnvironment: بارگذاری محیط Node.js و اجرای کد.
  • node::SpinEventLoop: اجرای حلقهٔ رویداد تا پایان کار.
  • node::Stop: توقف حلقهٔ رویداد به‌صورت دستی.
MaybeLocal loadenv_ret = node::LoadEnvironment(
    env,
    "const publicRequire = require('node:module').createRequire(process.cwd() + '/');"
    "globalThis.require = publicRequire;"
    "require('node:vm').runInThisContext(process.argv[1]);");

if (loadenv_ret.IsEmpty()) return 1;
exit_code = node::SpinEventLoop(env).FromMaybe(1);
node::Stop(env);

نتیجه‌گیری


C++ Embedder API در Node.js ابزاری قدرتمند برای اجرای جاوااسکریپت درون نرم‌افزارهای C++ است. با مدیریت وضعیت سراسری و نمونه‌ای، و استفاده از APIهایی مانند LoadEnvironment و SpinEventLoop، توسعه‌دهندگان می‌توانند برنامه‌های ترکیبی بسازند که از قدرت Node.js و C++ به‌طور همزمان بهره‌مند شوند.

نوشته و پژوهش شده توسط دکتر شاهین صیامی