.init
/ .fini
অবচয়হীন নয়। এটি এখনও ইএলএফ স্ট্যান্ডার্ডের একটি অংশ এবং আমি সাহস করে বলতে পারি যে এটি চিরকাল থাকবে। কোড লোড / আনলোড করা অবস্থায় কোড ইন .init
/ .fini
লোডার / রানটাইম-লিঙ্কার দ্বারা চালিত হয়। অর্থাৎ প্রতিটি ইএলএফ লোডের উপর (উদাহরণস্বরূপ একটি ভাগ করা লাইব্রেরি) কোড .init
চালানো হবে। এখনও একই জিনিসটি অর্জন করতে সেই প্রক্রিয়াটি ব্যবহার করা সম্ভব __attribute__((constructor))/((destructor))
। এটি পুরাতন স্কুল তবে এর কিছু সুবিধা রয়েছে।
.ctors
/ .dtors
প্রক্রিয়া উদাহরণস্বরূপ সিস্টেম-rtl / লোডার / লিঙ্কার-স্ক্রিপ্ট দ্বারা সমর্থন প্রয়োজন। এটি সমস্ত সিস্টেমে উপলভ্য হওয়া অনেক দূরে, উদাহরণস্বরূপ গভীরভাবে এম্বেড হওয়া সিস্টেমগুলি যেখানে কোডটি বেয়ার ধাতব উপর কার্যকর করে। __attribute__((constructor))/((destructor))
যেমন জিসিসি সমর্থিত হলেও এটি নিশ্চিত নয় যে এটি পরিচালনা করবে লিঙ্কার এবং এটি চালানোর জন্য লোডার (বা কিছু ক্ষেত্রে, বুট-কোড) এর উপর নির্ভর করে। ব্যবহার .init
/ .fini
পরিবর্তে, সবচেয়ে সহজ উপায় হ'ল লিঙ্কার পতাকা ব্যবহার করা: -আইনিট & -ফিনি (যেমন জিসিসি কমান্ড লাইন থেকে, বাক্য গঠনটি হবে -Wl -init my_init -fini my_fini
)।
উভয় পদ্ধতি সমর্থনকারী সিস্টেমে, একটি সম্ভাব্য সুবিধা হ'ল কোডটি .init
আগে চালানো হয় .ctors
এবং .fini
পরে কোড করা হয় .dtors
। যদি অর্ডার প্রাসঙ্গিক হয় তবে কমপক্ষে একটি অপরিশোধিত তবে init / প্রস্থান ফাংশনগুলির মধ্যে পার্থক্য করার সহজ উপায়।
একটি বড় অসুবিধা হ'ল আপনি সহজেই প্রতিটি লোডযোগ্য মডিউল প্রতি এক _init
এবং একাধিক _fini
ফাংশন রাখতে পারবেন না এবং সম্ভবত .so
উদ্দেশ্যপ্রণোদিতের চেয়ে বেশি অংশে কোড টুকরো করতে হবে । অন্যটি হ'ল উপরে বর্ণিত লিঙ্কার পদ্ধতিটি ব্যবহার করার সময়, একটি আসল _ ইনট এবং _fini
ডিফল্ট ফাংশন (সরবরাহিত crti.o
) প্রতিস্থাপন করে । এখানেই সব ধরণের সূচনা সাধারণত ঘটে থাকে (লিনাক্স এ এটি যেখানে গ্লোবাল ভেরিয়েবল অ্যাসাইনমেন্ট শুরু করা হয়)। প্রায় একটি উপায় এখানে বর্ণিত হয়
উপরের লিঙ্কে লক্ষ্য করুন যে আসলটিতে _init()
এখনও ক্যাসকেডিংয়ের প্রয়োজন নেই কারণ এটি এখনও রয়েছে। দ্যcall
ইনলাইন সমাবেশ তবে এ এক্স 86-স্মৃতিসম্বন্ধীয় এবং একটি ফাংশন সমাবেশ (উদাহরণস্বরূপ এআরএম মত) অনেক অন্যান্য আর্কিটেকচারের জন্য সম্পূর্ণ ভিন্ন দেখাবে থেকে কল করা হয়। অর্থাৎ কোড স্বচ্ছ নয়।
.init
/ .fini
এবং .ctors
/ .detors
প্রক্রিয়া সমান, তবে বেশ নয়। মধ্যে Code .init
/ .fini
রানে "যেমন আছে"। অর্থাৎ আপনার .init
/ এ বেশ কয়েকটি কার্যকারিতা থাকতে পারে .fini
, তবে অনেক ছোট .so
ফাইলগুলিতে কোড না ভেঙে এফআইকে সিনট্যাকটিক্যালি এগুলি সম্পূর্ণরূপে স্বচ্ছ সিতে রেখে দেওয়া কঠিন ।
.ctors
/ .dtors
ভিন্নভাবে চেয়ে সংগঠিত .init
/ .fini
। .ctors
/ .dtors
বিভাগগুলি উভয়ই ফাংশনগুলিতে পয়েন্টার সহ কেবল সারণী এবং "কলার" একটি সিস্টেম-সরবরাহিত লুপ যা প্রতিটি ফাংশনকে পরোক্ষভাবে ডাকে। লুপ-কলারটি আর্কিটেকচার নির্দিষ্ট হতে পারে তবে এটি সিস্টেমের অংশ হিসাবে (এটি যদি বাস্তবে বিদ্যমান থাকে তবে) তাতে কিছু আসে যায় না।
নিম্নলিখিত স্নিপেট .ctors
ফাংশন অ্যারেতে নতুন ফাংশন পয়েন্টার যুক্ত করে , মূলত একইভাবে __attribute__((constructor))
(পদ্ধতি সহ সহাবস্থান করতে পারে) __attribute__((constructor)))
।
#define SECTION( S ) __attribute__ ((section ( S )))
void test(void) {
printf("Hello\n");
}
void (*funcptr)(void) SECTION(".ctors") =test;
void (*funcptr2)(void) SECTION(".ctors") =test;
void (*funcptr3)(void) SECTION(".dtors") =test;
একটি সম্পূর্ণ ভিন্ন স্ব-উদ্ভাবিত বিভাগে ফাংশন পয়েন্টার যুক্ত করতে পারে। পরিবর্তিত লিঙ্কার স্ক্রিপ্ট এবং এ জাতীয় ক্ষেত্রে লোডার .ctors
/ .dtors
লুপের নকল করা একটি অতিরিক্ত ফাংশন প্রয়োজন। তবে এটির মাধ্যমে এক্সিকিউশন অর্ডারের উপর আরও ভাল নিয়ন্ত্রণ অর্জন করা যায়, ইন-আর্গুমেন্ট এবং রিটার্ন কোড হ্যান্ডলিং এটা (উদাহরণস্বরূপ, সি ++ প্রকল্পে, বৈশ্বিক নির্মাণকারীদের আগে বা পরে কিছু চালানোর প্রয়োজনে এটি কার্যকর হবে)।
আমি __attribute__((constructor))/((destructor))
যেখানে সম্ভব তা পছন্দ করি , এটি একটি সহজ এবং মার্জিত সমাধান এমনকি এটি প্রতারণার মতো বলে মনে হয়। আমার মতো খালি ধাতব কোডারদের জন্য, এটি সর্বদা একটি বিকল্প নয়।
লিঙ্কারস এবং লোডার বইয়ের কিছু ভাল রেফারেন্স ।
#define __attribute__(x)
) সহজ করে তোলে । আপনার যদি একাধিক বৈশিষ্ট্য থাকে, যেমন,__attribute__((noreturn, weak))
যদি বন্ধনীর এক সেট থাকে তবে "ম্যাক্রো আউট" করা শক্ত হবে।