Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रूबी C एक्सटेंशन में महारत: स्क्रैच से हाई-परफॉरमेंस मॉड्यूल बनाएं

रूबी मैजिक के इस संस्करण में, हम आपको दिखाएंगे कि C में लिखे गए कोड का उपयोग रूबी से कैसे करें। इसका उपयोग आपके कोड के प्रदर्शन-संवेदनशील भागों को अनुकूलित करने के लिए या C लाइब्रेरी और रूबी के बीच एक इंटरफेस बनाने के लिए किया जा सकता है। यह C में लिखी गई लाइब्रेरीज़ को रैप करने वाले एक्सटेंशन बनाकर किया जाता है।

C में लिखी गई बहुत सारी परिपक्व और प्रदर्शनशील लाइब्रेरीज़ हैं। उन्हें पोर्ट करके पहिया को फिर से आविष्कार करने के बजाय हम इन लाइब्रेरीज़ का रूबी से लाभ उठा सकते हैं। इस तरह, हम अपनी पसंदीदा भाषा में कोड करते हैं, जबकि उन क्षेत्रों में C लाइब्रेरीज़ का उपयोग करते हैं जहां रूबी पारंपरिक रूप से मजबूत नहीं है। ऐपसिग्नल पर, हमने rdkafka जेम विकसित करने में इस दृष्टिकोण का उपयोग किया है।

तो आइए देखें कि कोई इस दृष्टिकोण को कैसे अपना सकता है। यदि आप साथ चलना चाहते हैं और स्वयं प्रयोग करना चाहते हैं, तो उदाहरण कोड देखें। शुरू करने के लिए, आइए रूबी कोड के इस टुकड़े को लें जिसमें एक स्ट्रिंग, एक नंबर और एक बूलियन है (आप C देखेंगे क्यों, इरादा उद्देश्य) और इसे C लाइब्रेरी में पोर्ट करें:

module CFromRubyExample class Helpers def self.string(value) "String: '#{value}'" end def self.number(value) value + 1 end def self.boolean(value) !value end end end

क्रमशः, दिखाए गए तरीके एक स्ट्रिंग को जोड़ते हैं, एक नंबर को एक से बढ़ाते हैं और बूलियन के विपरीत को लौटाते हैं।

हमारी लाइब्रेरी C में पोर्ट की गई

नीचे, आप C में पोर्ट किए गए कोड को देख सकते हैं। C स्टैंडर्ड लाइब्रेरी और IO लाइब्रेरी शामिल हैं ताकि हम स्ट्रिंग फॉर्मेटिंग का उपयोग कर सकें। हम रूबी String के बजाय char* का उपयोग करते हैं। char* मेमोरी में कहीं कैरेक्टर्स के बफर के स्थान की ओर इंगित करता है।

# include <stdlib.h> # include <stdio.h> char* string_from_library(char* value) { char* out = (char*)malloc(256 * sizeof(char)); sprintf(out, "String: '%s'", value); return out; } int number_from_library(int value) { return value + 1; } int boolean_from_library(int value) { if (value == 0) { return 1; } else { return 0; } }

जैसा कि आप देख सकते हैं, साधारण स्ट्रिंग फॉर्मेटिंग करने के लिए आपको कुछ हुप्स से कूदना पड़ता है। एक स्ट्रिंग को जोड़ने के लिए, हमें पहले एक बफर आवंटित करना होगा। इसके साथ, sprintf फ़ंक्शन तब फॉर्मेटेड परिणाम को इसमें लिख सकता है। अंत में, हम बफर को वापस कर सकते हैं।

उपरोक्त कोड के साथ, हमने पहले से ही एक संभावित क्रैश या सुरक्षा समस्या पेश की है। यदि आने वाली स्ट्रिंग 245 बाइट्स से अधिक लंबी है, तो डरावना बफर ओवरफ्लो होगा। C लिखते समय आपको निश्चित रूप से सावधान रहना चाहिए, अपने पैर पर गोली मारना आसान है।

अगला एक हेडर फाइल है:

char* string_from_library(char*); int number_from_library(int); int boolean_from_library(int);

यह फाइल हमारे C लाइब्रेरी के पब्लिक API का वर्णन करती है। अन्य प्रोग्राम इसका उपयोग यह जानने के लिए करते हैं कि लाइब्रेरी में कौन से फ़ंक्शन्स कॉल किए जा सकते हैं।

2018 का तरीका: ffi जेम का उपयोग करें

तो, हमारे पास अब एक C लाइब्रेरी है जिसे हम रूबी से उपयोग करना चाहते हैं। इस C कोड को जेम में रैप करने के दो तरीके हैं। आधुनिक तरीका ffi जेम का उपयोग करना शामिल है। यह कई हुप्स को स्वचालित करता है जिनसे हमें कूदना पड़ता है। हमारे द्वारा अभी लिखे गए C कोड के साथ ffi का उपयोग करना इस तरह दिखता है:

module CFromRubyExample class Helpers extend FFI::Library ffi_lib File.join(File.dirname(__FILE__), "../../ext/library.so") attach_function :string, [:string], :string attach_function :number, [:int], :int attach_function :boolean, [:int], :int end end

इस लेख के उद्देश्य के लिए, हम यह भी समझाने जा रहे हैं कि C एक्सटेंशन के साथ C कोड को कैसे रैप किया जाए। यह हमें इस बात की बहुत अधिक अंतर्दृष्टि देगा कि रूबी में हुड के नीचे यह सब कैसे काम करता है।

हमारी लाइब्रेरी को C एक्सटेंशन में रैप करना

तो हमारे पास अब एक C लाइब्रेरी है जिसे हम रूबी से उपयोग करना चाहते हैं। अगला कदम एक जेम बनाना है जो इसे कंपाइल और रैप करता है। जेम बनाने के बाद, हम पहले ext को gemspec में require_paths में जोड़ते हैं:

Gem::Specification.new do |spec| spec.name = "c_from_ruby_example" # ... spec.require_paths = ["lib", "ext"] end

यह रूबीजेम्स को सूचित करता है कि एक नेटिव एक्सटेंशन है जिसे बनाने की आवश्यकता है। यह extconf.rb या Rakefile नामक फाइल की तलाश करेगा। इस मामले में, हमने extconf.rb जोड़ा:

require "mkmf" create_makefile "extension"

हम mkmf की आवश्यकता करते हैं, जो "Make Makefile" के लिए खड़ा है। यह रूबी के साथ शामिल हेल्पर्स का एक सेट है जो C बिल्ड सेटअप प्राप्त करने के पेचीदा हिस्से को समाप्त करता है। हम create_makefile को कॉल करते हैं और एक्सटेंशन के लिए एक नाम सेट करते हैं। यह एक Makefile बनाता है जिसमें C कोड को बनाने के लिए सभी कॉन्फ़िगरेशन और कमांड्स होते हैं।

अब, लाइब्रेरी को रूबी से जोड़ने के लिए कुछ C कोड लिखने की आवश्यकता है। हम कुछ फ़ंक्शन्स बनाएंगे जो C टाइप्स जैसे char* को रूबी टाइप्स जैसे String में कनवर्ट करते हैं। फिर हम C कोड के साथ एक रूबी क्लास बनाएंगे।

सबसे पहले, हम रूबी से कुछ हेडर फाइल्स शामिल करते हैं। ये उन फ़ंक्शन्स को आयात करेंगे जिनकी हमें टाइप कन्वर्जन के लिए आवश्यकता है। हम पहले बनाई गई library.h हेडर फाइल को भी शामिल करते हैं ताकि हम अपनी लाइब्रेरी को कॉल कर सकें।

#include "ruby/ruby.h" #include "ruby/encoding.h" #include "library.h"

हम फिर अपनी लाइब्रेरी में प्रत्येक फ़ंक्शन को रैप करने के लिए एक फ़ंक्शन बनाते हैं। यह स्ट्रिंग के लिए है:

static VALUE string(VALUE self, VALUE value) { Check_Type(value, T_STRING); char* pointer_in = RSTRING_PTR(value); char* pointer_out = string_from_library(pointer_in); return rb_str_new2(pointer_out); }

हम पहले जांचते हैं कि आने वाला रूबी मान एक स्ट्रिंग है, क्योंकि एक गैर-स्ट्रिंग मान को प्रोसेस करने से सभी प्रकार के बग हो सकते हैं। हम फिर रूबी String को char* में RSTRING_PTR हेल्पर मैक्रो के साथ कनवर्ट करते हैं जो रूबी प्रदान करता है। हम अब अपनी C लाइब्रेरी को कॉल कर सकते हैं। लौटाए गए char* को कनवर्ट करने के लिए, हम शामिल rb_str_new2 फ़ंक्शन का उपयोग करते हैं। हम नंबर और बूलियन के लिए समान रैपिंग फ़ंक्शन्स जोड़ेंगे।

संख्याओं के लिए, हम NUM2INT और INT2NUM हेल्पर्स का उपयोग करके कुछ समान करते हैं:

static VALUE number(VALUE self, VALUE value) { Check_Type(value, T_FIXNUM); int number_in = NUM2INT(value); int number_out = number_from_library(number_in); return INT2NUM(number_out); }

बूलियन संस्करण भी समान है। ध्यान दें कि C में वास्तव में बूलियन प्रकार नहीं है। कन्वेंशन इसके बजाय 0 और 1 का उपयोग करना है।

static VALUE boolean(VALUE self, VALUE value) { int boolean_in = RTEST(value); int boolean_out = boolean_from_library(boolean_in); if (boolean_out == 1) { return Qtrue; } else { return Qfalse; } }

अंत में, हम सब कुछ वायर अप कर सकते हैं ताकि हम इसे रूबी से कॉल कर सकें:

void Init_extension(void) { VALUE CFromRubyExample = rb_define_module("CFromRubyExample"); VALUE NativeHelpers = rb_define_class_under(CFromRubyExample, "NativeHelpers", rb_cObject); rb_define_singleton_method(NativeHelpers, "string", string, 1); rb_define_singleton_method(NativeHelpers, "number", number, 1); rb_define_singleton_method(NativeHelpers, "boolean", boolean, 1); }

हां, आपने सही पढ़ा: हम C में रूबी मॉड्यूल्स, क्लासेस और मेथड्स बना सकते हैं। हम यहां अपनी क्लास सेट करते हैं। फिर हम क्लास में रूबी मेथड्स जोड़ते हैं। हमें रूबी मेथड का नाम, उस C रैपर फ़ंक्शन का नाम प्रदान करना होगा जिसे कॉल किया जाएगा, और आर्गुमेंट्स की संख्या दर्शानी होगी।

उस सारे काम के बाद, हम अंततः अपने C कोड को कॉल कर सकते हैं:

CFromRubyExample::NativeHelpers.string("a string")

निष्कर्ष

हम हुप्स से कूदे, क्रैश नहीं हुए, और अपना C एक्सटेंशन काम करने लगा। C एक्सटेंशन लिखना कमजोर दिल वालों के लिए नहीं है। ffi जेम का उपयोग करते समय भी आप अपने रूबी प्रोसेस को काफी आसानी से क्रैश कर सकते हैं। लेकिन यह करने योग्य है और आपके लिए प्रदर्शनशील और स्थिर C लाइब्रेरीज़ की एक दुनिया खोल सकता है!

  1. रूबी इंटरप्रेटर बनाना: भाग 2 – एक कस्टम प्रोग्रामिंग भाषा का निर्माण रूबी इंटरप्रेटर बनाना: भाग 2 – एक कस्टम प्रोग्रामिंग भाषा का निर्माण

    गिटहब पर पूर्ण स्रोत स्टॉफल प्रोग्रामिंग भाषा का पूरा कार्यान्वयन गिटहब पर उपलब्ध है। यदि आपको बग मिलें या कोई प्रश्न हों तो बेझिझक एक इश्यू खोलें। इस ब्लॉग पोस्ट में, हम स्टॉफल के लिए इंटरप्रेटर को लागू करना जारी रखेंगे, जो पूरी तरह से रूबी में बनी एक खिलौना प्रोग्रामिंग भाषा है। हमने पिछले पोस्ट

  1. Stoffle भाषा के लिए Ruby इंटरप्रेटर बनाना Stoffle भाषा के लिए Ruby इंटरप्रेटर बनाना

    GitHub पर पूर्ण स्रोत Stoffle प्रोग्रामिंग भाषा का एक पूर्ण कार्यान्वयन GitHub पर उपलब्ध है। यदि आपको बग मिलते हैं या आपके कोई प्रश्न हैं तो बेझिझक एक इश्यू खोलें। इस ब्लॉग पोस्ट में, हम Stoffle के लिए इंटरप्रेटर को लागू करना शुरू करने जा रहे हैं, एक खिलौना प्रोग्रामिंग भाषा जिसे पूरी तरह से

  1. चरण-दर-चरण: USB ड्राइव का उपयोग करके स्क्रैच से विंडोज 11 इंस्टॉल करें चरण-दर-चरण: USB ड्राइव का उपयोग करके स्क्रैच से विंडोज 11 इंस्टॉल करें

    माइक्रोसॉफ्ट ने विंडोज 11 जारी किया है, दुनिया में सबसे अधिक उपयोग किए जाने वाले कंप्यूटर ऑपरेटिंग सिस्टम का नया संस्करण। विंडोज 11 ऑपरेटिंग सिस्टम के नवीनतम संस्करण में गेमिंग पर्क्स, सरलीकृत लेआउट, सहज शॉर्टकट और बहुत कुछ सहित कई नई सुविधाएं हैं। यदि आपके पास एक विंडोज 10 कंप्यूटर है जो विंडोज 11