কম্পিউটার

কিভাবে একটি রুবি সি এক্সটেনশন লিখবেন (ধাপে ধাপে)

একটি C এক্সটেনশন লেখার ফলে আপনি C থেকে রুবির সাথে যোগাযোগ করতে পারবেন।

আপনি এটি চাইতে পারেন যদি একটি বিশেষ গুরুত্বপূর্ণ পদ্ধতি থাকে যা আপনি C এর গতির সাথে অপ্টিমাইজ করতে চান, অথবা যদি আপনি একটি C লাইব্রেরি এবং রুবির মধ্যে একটি ইন্টারফেস তৈরি করতে চান৷

একটি বিকল্প FFI মডিউল ব্যবহার করা হবে।

এখন :

আসুন আবিষ্কার করি কিভাবে একটি C এক্সটেনশন লিখতে হয়!

আপনার প্রথম সি এক্সটেনশন

extconf.rb নামে একটি ফাইল তৈরি করুন এই বিষয়বস্তু সহ:

require 'mkmf'

create_header
create_makefile 'foobar'

তারপর ruby extconf.rb চালান যা আপনার জন্য কয়েকটি ফাইল তৈরি করবে (Makefile &extconf.h ) এই ফাইলগুলি পরিবর্তন করবেন না।

এখন foobar.c তৈরি করুন , এই নামটি এসেছে create_makefile থেকে extconf.rb-এ লাইন . আপনি চাইলে এটি পরিবর্তন করতে পারেন তবে এটি আপনার .c এর সাথে মেলে এটি কাজ করার জন্য ফাইলের নাম৷

foobar.c এর ভিতরে আপনি এটি যোগ করুন:

#include "ruby.h"
#include "extconf.h"

void Init_foobar()
{
  // Your C code goes here
}

এটি আপনার সি এক্সটেনশনের মৌলিক কঙ্কাল। লক্ষ্য করুন যে আপনাকে extconf.rb-এ ঘোষিত নামটি ব্যবহার করতে হবে সাথে Init_ শব্দটি . এই ক্ষেত্রে Init_foobar .

আপনি make চালিয়ে এটি কম্পাইল করতে পারেন , এবং আপনি যা পাবেন তা হল একটি so ফাইল যা আপনি require ব্যবহার করে আপনার রুবি অ্যাপ্লিকেশনে লোড করতে পারেন .

C থেকে একটি রুবি পদ্ধতি লেখা

আপনি সি ফাংশন তৈরি করতে পারেন যা আপনি আপনার রুবি কোড থেকে কল করতে পারেন। এইভাবে বিল্ট-ইন ক্লাস এবং পদ্ধতিগুলি কাজ করে।

সমস্ত রুবি পদ্ধতিতে একটি VALUE ফেরত দিতে হবে . একটি VALUE একটি রুবি বস্তু।

উদাহরণ :

VALUE rb_return_nil() {
  return Qnil;
}

এখন আমাদের এই ফাংশনটিকে রুবি ক্লাস বা মডিউলের সাথে সংযুক্ত করতে হবে। আপনি একটি নতুন ক্লাস তৈরি করতে পারেন বা বিদ্যমান একটি ব্যবহার করতে পারেন৷

এখানে আমি একটি মডিউল তৈরি করছি :

void Init_foobar() {
  VALUE mod = rb_define_module("RubyGuides");

  rb_define_method(mod, "return_nil", rb_return_nil, 0);
}

আপনি rb_define_method ব্যবহার করতে পারেন এই মডিউলে সি ফাংশন সংযুক্ত করার পদ্ধতি।

যুক্তি হল :

আর্গুমেন্ট বর্ণনা
mod মডিউল অবজেক্ট
“print_hello” রুবি পদ্ধতির নাম
rb_print_hello C ফাংশনের নাম
0 এই পদ্ধতিতে যত আর্গুমেন্ট লাগে, পরিবর্তনশীল আর্গুমেন্টের জন্য -1 ব্যবহার করুন

এখন make চালান আবার এক্সটেনশন কম্পাইল করতে, এবং এটি এই মত চেষ্টা করুন:

require 'foobar'

include RubyGuides
print_hello

আপনি সেখানে যান, আপনি রুবি থেকে একটি সি ফাংশন কল করেছেন!

C থেকে একটি রুবি হ্যাশ তৈরি করা

প্রায়শই আপনি C.

থেকে রুবি অবজেক্ট তৈরি এবং ম্যানিপুলেট করতে চান

আপনি C API ব্যবহার করে এটি করতে পারেন।

উদাহরণস্বরূপ, একটি হ্যাশ তৈরি করতে এবং এতে কিছু উপাদান যুক্ত করতে:

VALUE create_hash() {
  hash = rb_hash_new();

  rb_hash_aset(hash, rb_str_new2("test"), INT2FIX(1));
  return hash;
}

এখানে দুটি গুরুত্বপূর্ণ বিষয় লক্ষ্য করতে হবে, প্রথমে rb_str_new2 ফাংশন, এটি একটি রুবি স্ট্রিং তৈরি করে।

তারপর INT2FIX ম্যাক্রো, এটি একটি নিয়মিত পূর্ণসংখ্যাকে রুবি পূর্ণসংখ্যাতে রূপান্তর করে।

এখন যদি আপনি rb_define_method ব্যবহার করে এই ফাংশনটি রুবির কাছে প্রকাশ করেন আপনি একটি কী সহ একটি নিয়মিত রুবি হ্যাশ পাবেন (test ) এবং 1 এর একটি মান .

প্রতিবার আপনি পরিবর্তন করার সময় আপনার এক্সটেনশন পুনরায় কম্পাইল করতে ভুলবেন না 🙂

স্ট্রিংগুলির সাথে কাজ করা

আপনার সি ফাংশনগুলিও প্যারামিটার নিতে পারে।

যেমন:

VALUE rb_print_length(VALUE self, VALUE str) {
  if (RB_TYPE_P(str, T_STRING) == 1) {
    return rb_sprintf("String length: %ld", RSTRING_LEN(str));
  }

  return Qnil;
}

void Init_foobar()
{
  rb_define_global_function("print_length", rb_print_length, 1);
}

এখানে আমরা একটি VALUE নিচ্ছি (রুবি অবজেক্ট) একটি যুক্তি হিসাবে এবং তারপরে আমরা নিশ্চিত করি যে এটি RB_TYPE_P সহ একটি স্ট্রিং ম্যাক্রো এর পরে, আমরা শুধু RSTRING_LEN ব্যবহার করে স্ট্রিং দৈর্ঘ্য প্রিন্ট করি ম্যাক্রো।

আপনি যদি স্ট্রিং ডেটাতে একটি পয়েন্টার চান তাহলে আপনি RSTRING_PTR ব্যবহার করতে পারেন ম্যাক্রো।

উদাহরণ :

VALUE rb_print_data(VALUE self, VALUE str) {
  if (RB_TYPE_P(str, T_STRING) == 1) {
    return rb_sprintf("String length: %s", RSTRING_LEN(str));
  }

  return Qnil;
}
ফেরত দিন

এছাড়াও এখানে কিভাবে আরেকটি প্যারামিটার আছে তা লক্ষ্য করুন, self , এই বস্তুটি পদ্ধতি কল গ্রহণ করে।

আপনি যদি স্ট্রিং ক্লাসে এই পদ্ধতিটি সংজ্ঞায়িত করতে চান তবে আপনি এটি এভাবে করবেন:

void Init_foobar()
{
  rb_define_method(rb_cString, "print_length", rb_print_length, 0);
}

সারাংশ

আপনি রুবির জন্য একটি সি এক্সটেনশন কীভাবে লিখতে হয় তা শিখেছেন যাতে আপনি আপনার রুবি প্রোগ্রামগুলি থেকে সি এর সমস্ত শক্তি অ্যাক্সেস করতে পারেন। আপনি রুবিতে সি ফাংশনগুলিকে কীভাবে প্রকাশ করতে হয় এবং সি থেকে রুবি অবজেক্টের সাথে কীভাবে কাজ করতে হয়, যেমন স্ট্রিং এবং হ্যাশের সাথে কাজ করতে হয় তাও শিখেছেন৷

সি থেকে রুবির সাথে ইন্টারঅ্যাক্ট করার জন্য আপনার যদি আরও ফাংশনের প্রয়োজন হয় তবে আপনাকে রুবির সোর্স কোডে এবং সি এক্সটেনশন কোড পড়তে হতে পারে কারণ এটি ভালভাবে নথিভুক্ত নয়৷

আশা করি আপনি এই নিবন্ধটি দরকারী এবং আকর্ষণীয় পেয়েছেন! যদি আপনি এটি আপনার বন্ধুদের সাথে শেয়ার করুন যাতে তারাও এটি উপভোগ করতে পারে৷


  1. একটি ম্যাট্রিক্স কি এবং রুবিতে এটি কীভাবে ব্যবহার করবেন?

  2. রুবিতে স্ট্রাকট এবং ওপেনস্ট্রাক্ট কীভাবে ব্যবহার করবেন

  3. রুবিতে একটি পোর্ট স্ক্যানার কীভাবে লিখবেন

  4. রুবিতে ফাইলগুলি কীভাবে পড়তে এবং লিখতে হয় (উদাহরণ সহ)