যদি আমার কাছে দুটি লাইব্রেরি থাকে যা সমান নাম সহ ফাংশন সরবরাহ করে তবে আমার কী করা উচিত?
vorbis_...
, sf_...
, sdl_...
)। এটি মূলত যা সি ++ নাম-গতি ফাংশনগুলির জন্য প্রতীক নামগুলিতে করে।
যদি আমার কাছে দুটি লাইব্রেরি থাকে যা সমান নাম সহ ফাংশন সরবরাহ করে তবে আমার কী করা উচিত?
vorbis_...
, sf_...
, sdl_...
)। এটি মূলত যা সি ++ নাম-গতি ফাংশনগুলির জন্য প্রতীক নামগুলিতে করে।
উত্তর:
এপ্রোপস মন্তব্যগুলি: "রফতানি" বলতে আমার অর্থ লাইব্রেরির সাথে সংযোগকারী মডিউলগুলিকে দৃশ্যমান করা --- extern
ফাইল স্কোপে কীওয়ার্ডের সমতুল্য । এটি কীভাবে নিয়ন্ত্রণ করা হয় তা ওএস এবং লিঙ্কার নির্ভর। এবং এটি এমন কিছু যা আমাকে সর্বদা সন্ধান করতে হবে।
কোনও অবজেক্ট ফাইলে objcopy --redefine-sym old=new file
প্রতীকটির নাম পরিবর্তন করা সম্ভব (ম্যান অ্যাজকপিটি দেখুন)।
তারপরে কেবল তাদের নতুন নামগুলি ব্যবহার করে ফাংশনগুলিতে কল করুন এবং নতুন অবজেক্ট ফাইলের সাথে লিঙ্ক করুন।
উইন্ডোজ এর অধীনে, আপনি সেই লাইব্রেরিগুলির একটি মেমরিতে লোড করতে লোডলাইবারি () ব্যবহার করতে পারেন এবং তারপরে ফাংশন পয়েন্টারের মাধ্যমে ফাংশনগুলিতে কল এবং কল করতে হবে এমন প্রতিটি ফাংশনের ঠিকানা পেতে গেটপ্রোকএড্রেস () ব্যবহার করতে পারেন use
যেমন
HMODULE lib = LoadLibrary("foo.dll");
void *p = GetProcAddress(lib, "bar");
// cast p to the approriate function pointer type (fp) and call it
(*fp)(arg1, arg2...);
FreeLibrary(lib);
foo.dll এ বার নামে একটি ফাংশনের ঠিকানা পেয়ে তা কল করবে।
আমি জানি ইউনিক্স সিস্টেমগুলি অনুরূপ কার্যকারিতা সমর্থন করে তবে আমি তাদের নামগুলি ভাবতে পারি না।
dlopen
dlsym
, এবং dlclose
। তবে ইউনিক্সের এনক্যাপসুলেশন উইন্ডোজের মতো কার্যকর নাও হতে পারে।
এখানে একটি চিন্তা। একটি হেক্স সম্পাদক সম্পাদকে আপত্তিজনক লাইব্রেরিগুলির একটি খুলুন এবং আপত্তিজনক স্ট্রিংয়ের সমস্ত উপস্থিতি অন্য কোনও কিছুতে পরিবর্তন করুন। তারপরে আপনার ভবিষ্যতের সমস্ত কলগুলিতে নতুন নামগুলি ব্যবহার করতে সক্ষম হওয়া উচিত।
আপডেট: আমি এই প্রান্তে এটি করেছি এবং এটি কার্যকর বলে মনে হচ্ছে। অবশ্যই, আমি এটি পুরোপুরি পরীক্ষা করে দেখিনি - হেক্সডিট শটগান দিয়ে আপনার পা কেটে ফেলার এটি সত্যিই ভাল উপায় ছাড়া আর কিছু নাও হতে পারে।
আপনার কাছে যদি .o ফাইল থাকে তবে এখানে একটি ভাল উত্তর: https://stackoverflow.com/a/6940389/4705766
সারসংক্ষেপ:
objcopy --prefix-symbols=pre_string test.o
.o ফাইলটিতে প্রতীকগুলির নাম পরিবর্তন করতে বা
objcopy --redefine-sym old_str=new_str test.o
.o ফাইলটিতে নির্দিষ্ট চিহ্নটির নতুন নামকরণ করতে।ধরে নিচ্ছি যে আপনি লিনাক্স ব্যবহার করেন আপনার প্রথমে যুক্ত করা দরকার
#include <dlfcn.h>
যথাযথ প্রসঙ্গে ফাংশন পয়েন্টার ভেরিয়েবল ঘোষণা করুন, উদাহরণস্বরূপ,
int (*alternative_server_init)(int, char **, char **);
Https://stackoverflow.com/a/678453/1635364 তে উল্লিখিত ফের্রুসিওর মতো , কার্যকর করে আপনি যে লাইব্রেরিটি ব্যবহার করতে চান তা লোড করুন (আপনার পছন্দসই পতাকাগুলি বেছে নিন)
void* dlhandle;
void* sym;
dlhandle = dlopen("/home/jdoe/src/libwhatnot.so.10", RTLD_NOW|RTLD_LOCAL);
আপনি যে ফাংশনটি পরে কল করতে চান তার ঠিকানাটি পড়ুন
sym = dlsym(dlhandle, "conflicting_server_init");
নিম্নলিখিত হিসাবে নির্ধারিত এবং নিক্ষিপ্ত
alternative_server_init = (int (*)(int, char**, char**))sym;
আসলটির চেয়ে একইভাবে কল করুন। শেষ পর্যন্ত, চালিয়ে আনলোড করুন
dlclose(dlhandle);
এগুলি একসাথে ব্যবহার করা উচিত নয়। যদি আমি সঠিকভাবে মনে রাখি তবে লিঙ্কার এ জাতীয় ক্ষেত্রে একটি ত্রুটি জারি করে।
আমি চেষ্টা না, কিন্তু একটি সমাধান সঙ্গে হতে পারে dlopen()
, dlsym()
এবং dlclose()
আপনি প্রোগ্রামের মাধ্যমে গতিশীল লাইব্রেরি হ্যান্ডেল করার অনুমতি দেয়। আপনার যদি একই সাথে দুটি ফাংশনের প্রয়োজন না হয় তবে আপনি প্রথম লাইব্রেরিটি খুলতে পারবেন, প্রথম ফাংশনটি ব্যবহার করতে পারবেন এবং দ্বিতীয় গ্রন্থাগার / ফাংশনটি ব্যবহার করার আগে প্রথম লাইব্রেরিটি বন্ধ করতে পারবেন।
এই সমস্যাটি হ'ল সি ++ এর নেমস্পেস রয়েছে। 2 টি তৃতীয় পক্ষের একই নাম সমেত লিবগুলির জন্য গিতে আসলেই দুর্দান্ত সমাধান নেই।
যদি এটি একটি গতিশীল অবজেক্ট হয় তবে আপনি সম্ভবত ভাগ করে নেওয়া অবজেক্টগুলি (লোডলিবারি / ড্লোপেন / ইত্যাদি) স্পষ্টভাবে লোড করতে সক্ষম হবেন এবং এটিকে ফ্যাশনে কল করতে পারবেন। পর্যায়ক্রমে, যদি একই কোডে আপনার একই সাথে উভয় লিবসের প্রয়োজন না হয় তবে আপনি স্থির লিঙ্কিংয়ের সাহায্যে কিছু করতে পারেন (যদি আপনার কাছে .lib / .a ফাইল থাকে)।
এই সমাধানগুলির কোনওটি অবশ্যই সমস্ত প্রকল্পের জন্য প্রযোজ্য নয়।
দিব্যি? যতদূর আমি সচেতন, আপনার কাছে দুটি লাইব্রেরি রয়েছে যা একই নামের সাথে লিঙ্ক পয়েন্টগুলি প্রকাশ করে এবং আপনার উভয়ের বিপরীতে লিঙ্ক করা দরকার হলে আপনি তেমন কিছু করতে পারবেন না।
আপনার মধ্যে একটির চারপাশে একটি মোড়ক লাইব্রেরি লেখা উচিত। আপনার মোড়কের লাইব্রেরিতে স্বতন্ত্র নামের প্রতীকগুলি প্রকাশ করা উচিত এবং অ-অনন্য নামের প্রতীকগুলি প্রকাশ করা উচিত নয়।
আপনার অন্য বিকল্পটি শিরোনাম ফাইলে ফাংশনটির নাম এবং লাইব্রেরি অবজেক্ট আর্কাইভের প্রতীকটির নতুন নামকরণ করা।
যে কোনও উপায়ে, উভয়ই ব্যবহার করা, এটি হ্যাকের কাজ হবে।
প্রশ্নটি এক দশক পুরানো কাছাকাছি পৌঁছেছে, তবে সর্বদা নতুন অনুসন্ধান রয়েছে ...
ইতিমধ্যে উত্তর হিসাবে, --redefine - সিম পতাকা সঙ্গে অবজকপি লিনাক্স মধ্যে ভাল পছন্দ। উদাহরণস্বরূপ, https://linux.die.net/man/1/objcopy দেখুন সম্পূর্ণ ডকুমেন্টেশনের জন্য । এটি কিছুটা জটিল কারণ আপনি পরিবর্তনগুলি করার সময় মূলত পুরো লাইব্রেরিটি অনুলিপি করছেন এবং প্রতিটি আপডেটের জন্য এই কাজটির পুনরাবৃত্তি করা প্রয়োজন। তবে কমপক্ষে এটি কাজ করা উচিত।
উইন্ডোজের জন্য, গতিময়ভাবে লাইব্রেরিটি লোড করা একটি সমাধান এবং লিনাক্সের ড্লোপেন বিকল্পের মতো স্থায়ীভাবে হবে। তবে ড্লোপেন () এবং লোডলিবারি () উভয়ই অতিরিক্ত কোড যুক্ত করে যা এড়ানো যেতে পারে যদি কেবলমাত্র ইস্যুটির নাম নকল হয়। এখানে উইন্ডোজ সলিউশনটি অ্যাজজকপি পদ্ধতির চেয়ে আরও মার্জিত: কেবল লিঙ্কারে বলুন যে কোনও লাইব্রেরির চিহ্নগুলি অন্য কোনও নামে পরিচিত এবং সেই নামটি ব্যবহার করুন। এটি করার কয়েকটি পদক্ষেপ রয়েছে। আপনাকে একটি ডিএফ ফাইল তৈরি করতে হবে এবং রফতানির বিভাগে নাম অনুবাদ সরবরাহ করতে হবে। Https://msdn.microsoft.com/en-us/library/hyx1zcd3.aspx দেখুন (VS2015, এটা শেষ পর্যন্ত নতুন সংস্করণে দ্বারা প্রতিস্থাপিত হবে) অথবা http://www.digitalmars.com/ctg/ctgDefFiles.html(সম্ভবত আরও স্থায়ী) একটি ডিএফ ফাইলের সম্পূর্ণ সিনট্যাক্স বিশদের জন্য। প্রক্রিয়াটি হ'ল লাইব্রেরির একটির জন্য একটি ডিএফ ফাইল তৈরি করে একটি ডিআইবি ফাইল তৈরির জন্য এই ডিএফ ফাইলটি ব্যবহার করুন এবং তারপরে সেই লিব ফাইলের সাথে লিঙ্ক করুন। (উইন্ডোজ ডিএলএলগুলির জন্য, লিব ফাইলগুলি কেবল লিঙ্কিংয়ের জন্য ব্যবহৃত হয়, কোড এক্সিকিউশন নয়)) লাইব ফাইলটি তৈরির প্রক্রিয়াটির জন্য একটি .dll ফাইল এবং একটি শিরোনাম ফাইল থাকাকালীন একটি .lib ফাইল কীভাবে তৈরি করবেন তা দেখুন । এখানে কেবলমাত্র পার্থক্যটিই ডাকনাম যুক্ত করা হচ্ছে।
লিনাক্স এবং উইন্ডোজ উভয়ের জন্যই, লাইব্রেরির শিরোনামগুলির ফাংশনগুলির নাম পরিবর্তন করুন যাদের নাম প্রবণতাযুক্ত রয়েছে। অন্য একটি বিকল্প যা কাজ করা উচিত তা হ'ল নতুন নামগুলি উল্লেখ করে ফাইলগুলিতে # ডিফাইন পুরাতন_নামের নতুন নাম, # লাইব্রেরির শিরোনামগুলি অন্তর্ভুক্ত করা হচ্ছে যার রফতানি আলাদা করে দেওয়া হচ্ছে, এবং তারপরে কলারের মধ্যে # অপরিষ্কার পুরাতন_নামের নাম অন্তর্ভুক্ত করুন। লাইব্রেরি ব্যবহার করে যদি অনেকগুলি ফাইল থাকে, তবে একটি সহজ বিকল্প হ'ল শিরোনাম বা শিরোনামগুলি তৈরি করে যা সংজ্ঞায়িত করে, অন্তর্ভুক্ত করে এবং আনডফগুলিকে আবৃত করে এবং তারপরে সেই শিরোনামটি ব্যবহার করে।
আশা করি এই তথ্যটি সহায়ক ছিল!
আমি কখনই dlsym, dlopen, dlerror, dlclose, dlvsym, ইত্যাদি ব্যবহার করি নি, তবে আমি ম্যান পৃষ্ঠাটি দেখছি, এবং এটি libm.so খোলার এবং কোস ফাংশনটি বের করার উদাহরণ দেয়। ড্লোপেন কি সংঘর্ষের সন্ধানের প্রক্রিয়াটি অতিক্রম করে? যদি এটি না হয় তবে ওপি কেবলমাত্র দুটি লাইব্রেরি ম্যানুয়ালি লোড করতে পারে এবং তার লাইব্রেরিগুলি সরবরাহ করে এমন সমস্ত কার্যক্রমে নতুন নাম নির্ধারণ করতে পারে।