এটি উইন্ডোজ এবং ইউনিক্সের মতো সিস্টেমের মধ্যে একটি দুর্দান্ত পার্থক্য।
যেভাই হোকনা কেন:
- প্রতিটি প্রক্রিয়াটির নিজস্ব ঠিকানা স্থান রয়েছে, যার অর্থ প্রসেসগুলির মধ্যে কখনই কোনও মেমরি ভাগ করা যায় না (যদি না আপনি কিছু আন্ত-প্রক্রিয়া যোগাযোগ গ্রন্থাগার বা এক্সটেনশান ব্যবহার করেন)।
- এক সংজ্ঞা রুল (ODR) এখনও প্রযোজ্য, যার অর্থ আপনি শুধুমাত্র বিশ্বব্যাপী পরিবর্তনশীল লিংক-সময় (স্ট্যাটিক বা গতিশীল লিঙ্ক) এ দৃশ্যমান এক সংজ্ঞা থাকতে পারে।
সুতরাং, এখানে মূল সমস্যাটি সত্যই দৃশ্যমানতা ।
সমস্ত ক্ষেত্রে, static
গ্লোবাল ভেরিয়েবল (বা ফাংশন) কোনও মডিউল (dll / so বা নির্বাহযোগ্য) এর বাইরে থেকে কখনই দৃশ্যমান হয় না। সি ++ স্ট্যান্ডার্ডের এগুলির অভ্যন্তরীণ যোগসূত্র থাকা আবশ্যক, যার অর্থ তারা অনুবাদ ইউনিটের বাইরে দৃশ্যমান নয় (যা কোনও বস্তুর ফাইল হয়ে যায়) যেখানে তারা সংজ্ঞায়িত হয়। সুতরাং, যে সমস্যা নিষ্পত্তি।
এটি যখন জটিল হয় তখন আপনার extern
বৈশ্বিক চলকগুলি হ'ল । এখানে, উইন্ডোজ এবং ইউনিক্সের মতো সিস্টেমগুলি সম্পূর্ণ আলাদা।
উইন্ডোজ (.exe এবং .dll) এর ক্ষেত্রে, extern
গ্লোবাল ভেরিয়েবলগুলি রফতানি চিহ্নগুলির অংশ নয়। অন্য কথায়, বিভিন্ন মডিউলগুলি কোনওভাবেই অন্যান্য মডিউলগুলিতে সংজ্ঞায়িত গ্লোবাল ভেরিয়েবল সম্পর্কে সচেতন নয়। এর অর্থ হ'ল আপনি যদি লিঙ্কার ত্রুটিগুলি পেয়ে থাকেন তবে উদাহরণস্বরূপ, একটি এক্সিকিউটেবল তৈরি করতে যা extern
ডিএলএল-এ সংজ্ঞায়িত ভেরিয়েবল ব্যবহার করার কথা বলে মনে করা হচ্ছে , কারণ এটি অনুমোদিত নয়। আপনাকে সেই বাহ্যিক ভেরিয়েবলের সংজ্ঞা সহ একটি অবজেক্ট ফাইল (বা স্ট্যাটিক লাইব্রেরি) সরবরাহ করতে হবে এবং এক্সিকিউটেবল এবং ডিএলএল উভয়ের সাথে এটি স্ট্যাটিকভাবে লিঙ্ক করতে হবে , যার ফলে দুটি স্বতন্ত্র গ্লোবাল ভেরিয়েবল (একটি এক্সিকিউটেবলের সাথে সম্পর্কিত এবং একটি ডিএলএল এর অন্তর্গত) )।
উইন্ডোজে আসলে গ্লোবাল ভেরিয়েবল এক্সপোর্ট করতে আপনাকে ফাংশন এক্সপোর্ট / ইম্পোর্ট সিনট্যাক্সের অনুরূপ একটি সিনট্যাক্স ব্যবহার করতে হবে, অর্থাত:
#ifdef COMPILING_THE_DLL
#define MY_DLL_EXPORT extern "C" __declspec(dllexport)
#else
#define MY_DLL_EXPORT extern "C" __declspec(dllimport)
#endif
MY_DLL_EXPORT int my_global;
আপনি যখন এটি করেন, বিশ্বব্যাপী পরিবর্তনশীল রফতানি চিহ্নগুলির তালিকায় যুক্ত হয় এবং অন্যান্য সমস্ত ফাংশনের মতো লিঙ্কযুক্ত হতে পারে can
ইউনিক্সের মতো পরিবেশের ক্ষেত্রে (লিনাক্সের মতো), ডায়নামিক লাইব্রেরিগুলি, " গ্লোবাল অবজেক্টস" নামে পরিচিত যা .so
সমস্ত extern
গ্লোবাল ভেরিয়েবল (বা ফাংশন) এক্সপোর্ট করে । এই ক্ষেত্রে, যদি আপনি লোড- টাইমকে যে কোনও জায়গা থেকে ভাগ করে নেওয়া অবজেক্ট ফাইলে সংযুক্ত করেন তবে গ্লোবাল ভেরিয়েবলগুলি ভাগ করা হবে, অর্থাত্ একটি হিসাবে একসাথে যুক্ত। মূলত, ইউনিক্স-এর মতো সিস্টেমগুলি এটির জন্য তৈরি করা হয়েছে যাতে কোনও স্ট্যাটিক বা ডায়নামিক লাইব্রেরির সাথে লিঙ্ক করার মধ্যে কার্যত কোনও পার্থক্য না থাকে। আবার, ওডিআর বোর্ড জুড়ে প্রযোজ্য: একটি extern
গ্লোবাল ভেরিয়েবল মডিউলগুলিতে ভাগ করা হবে, এর অর্থ এটি লোড হওয়া সমস্ত মডিউলগুলির মধ্যে কেবল একটি সংজ্ঞা থাকা উচিত।
অবশেষে, উভয় ক্ষেত্রেই উইন্ডোজ বা ইউনিক্সের মতো সিস্টেমের জন্য, আপনি গতিশীল লাইব্রেরির রান-টাইম লিঙ্কিং করতে পারেন , যেমন, LoadLibrary()
/ GetProcAddress()
/ FreeLibrary()
অথবা dlopen()
/ dlsym()
/ ব্যবহার করে dlclose()
। সেক্ষেত্রে আপনাকে ব্যবহার করতে ইচ্ছুক প্রতিটি প্রতীককে আপনাকে ম্যানুয়ালি পয়েন্টার পেতে হবে এবং এর মধ্যে আপনি ব্যবহার করতে চান এমন বৈশ্বিক পরিবর্তনগুলি অন্তর্ভুক্ত রয়েছে। গ্লোবাল ভেরিয়েবল জন্য, আপনি ব্যবহার করতে পারেন GetProcAddress()
বা dlsym()
ঠিক একই আপনার দেওয়া যে গ্লোবাল ভেরিয়েবল রপ্তানি প্রতীক তালিকা (পূর্ববর্তী অনুচ্ছেদের বিধি দ্বারা) এর অংশ হওয়ায়, কাজকর্মের জন্য কি হিসাবে।
এবং অবশ্যই, একটি চূড়ান্ত নোট হিসাবে: গ্লোবাল ভেরিয়েবলগুলি এড়ানো উচিত । এবং আমি বিশ্বাস করি যে আপনি যে পাঠ্যটি উদ্ধৃত করেছেন (বিষয়গুলি "অস্পষ্ট" সম্পর্কে) হুবহু প্ল্যাটফর্ম-নির্দিষ্ট পার্থক্যগুলির উল্লেখ করছে যা আমি কেবল ব্যাখ্যা করেছি (গতিশীল গ্রন্থাগারগুলি আসলে সি ++ স্ট্যান্ডার্ড দ্বারা সংজ্ঞায়িত করা হয় না, এটি প্ল্যাটফর্ম-নির্দিষ্ট অঞ্চল, যার অর্থ এটি অনেক কম নির্ভরযোগ্য / বহনযোগ্য)।