تسجيل كل ملف مصدر C/C++ لإنشاء قائمة وقت التشغيل بالمصادر المستخدمة

StackOverflow https://stackoverflow.com/questions/618581

سؤال

بالنسبة لمكتبة التصحيح والتسجيل، أريد أن أتمكن من العثور، في وقت التشغيل، على قائمة بجميع الملفات المصدر التي قام المشروع بتجميعها وربطها.أفترض أنني سأقوم بتضمين نوع من الرأس في كل ملف مصدر، ويمكن للماكرو __FILE__ للمعالج المسبق أن يمنحني حرفًا ثابتًا لهذا الملف، لذلك أحتاج فقط إلى "بث" تلك المعلومات من كل ملف بطريقة ما ليتم جمعها بواسطة وظيفة وقت التشغيل.

والسؤال هو كيفية القيام بذلك بشكل أنيق، وخاصة إذا كان من الممكن القيام بذلك من لغة C بدلاً من لغة C++.في لغة C++، ربما سأحاول إنشاء فصل دراسي مزود بتخزين ثابت للاحتفاظ بقائمة أسماء الملفات.من شأن كل ملف رأس أن ينشئ مثيلًا ثابتًا للملف المحلي لتلك الفئة، والذي عند إنشائه سيلحق مؤشر FILE أو أي شيء آخر بأعضاء البيانات الثابتة للفئة، ربما كقائمة مرتبطة.

لكنني لا أعتقد أن هذا سيعمل في لغة C، وحتى في لغة C++ لست متأكدًا من ضمان إنشاء كل عنصر.

هل كانت مفيدة؟

المحلول

لم أكن لأفعل هذا النوع من الشيء الصحيح في التعليمات البرمجية. أود أن أكتب الأداة التي تحليل ملف المشروع (vcproj، MAKEFILE أو حتى مجرد مسح لدليل المشروع ل* .C * الملفات) ولدت ملف إضافي مصدر C الذي يحتوي على أسماء جميع الملفات المصدر في نوع من مرحلة ما قبل هيكل البيانات تهيئة.

وأود أن ثم جعل هذه الأداة جزءا من عملية الإنشاء بحيث في كل مرة كنت تفعل بناء هذا من شأنه أن يحدث كل تلقائيا. في وقت التشغيل، كل ما يجب أن تفعله هو أن يقرأ بنية البيانات التي تم بناؤها.

نصائح أخرى

وأنا أتفق مع فيروتشيو، فإن أفضل طريقة للقيام بذلك هي في بناء نظام، وليس القانون نفسه. باعتبارها امتدادا لفكرته، إضافة الهدف لنظام بناء الخاصة بك والتي مقالب قائمة من الملفات (والتي لا بد أن تعلم على أي حال) إلى ملف C كسلسلة، أو مجموعة من السلاسل، وتجميع هذا الملف إلى المصدر. هذا يتجنب الكثير من المضاعفات في المصدر، وغير قابلة للتوسيع، إذا كنت ترغب في إضافة معلومات إضافية، مثل رقم الإصدار من نظام التحكم التعليمات البرمجية المصدر، الذي بنى القابل للتنفيذ، وما إلى ذلك.

وهناك طريقة قياسية على UNIX و Linux - ident. لكل ملف المصدر الذي خلق بطاقة هوية - عادة ما يتم تعيينه من قبلكم نظام التحكم في الإصدار، على سبيل المثال، SVN كلمات .

وبعد ذلك لمعرفة اسم ومراجعة كل ملف مصدر كنت تستخدم فقط قيادة ident. إذا كنت بحاجة إلى أن تفعل ذلك في وقت تحقق من مدى ident يفعل ذلك - مصدر لذلك ينبغي أن تكون متاحة بحرية

ولا توجد طريقة للقيام بذلك في C. في C ++ يمكنك إنشاء فئة مثل هذا:

struct Reg {
   Reg( const char * file ) {
      StaticDictionary::Register( file );
};

وحيث StaticDictionary هو حاوية المفرد لجميع أسماء الملفات الخاصة بك. ثم في كل ملف المصدر:

static Reg regthisfile( __FILE__ );

وأنت تريد أن تجعل القاموس على <لأ href = "http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Singleton-Pattern-Part- I / 4 / "يختلط =" نوفولو noreferrer "> مايرز المفرد لتجنب أمر من المشاكل الخلق.

وأنا لا أعتقد أنك تستطيع أن تفعل ذلك في الطريقة التي تحدد في وضع "السلبي". وهذا هو، وأنت تسير لتشغيل بطريقة أو بأخرى رمز لكل ملف المصدر الى أن تضاف إلى التسجيل، فإنه من الصعب أن يحصل هو أن يحدث تلقائيا.

وبطبيعة الحال، فإنه من الممكن أن تتمكن من تقديم هذا الرمز غير مزعجة جدا باستخدام وحدات الماكرو. قد يكون مشكلة بالنسبة لملفات المصدر C التي لم يكن لديك "نقطة الدخول"، حتى إذا لم يتم تنظيم التعليمات البرمجية بالفعل باسم "وحدات"، مع مثل وظيفة init() لكل وحدة، فإنه قد يكون من الصعب. قد يكون رمز تهيئة ثابت ممكن، وأنا لست متأكدا 100٪ إذا كان الترتيب الذي يتم تهيئة الأمور يخلق مشاكل هنا.

وعن طريق تخزين static في وحدة التسجيل يبدو وكأنه فكرة ممتازة، قائمة مرتبطة عادي أو جدول تجزئة بسيط يجب أن يكون من السهل بما فيه الكفاية لتنفيذ، إذا كان المشروع لا يشمل بالفعل أي مكتبة عامة الغرض فائدة.

في C++ سوف يعمل الحل الخاص بك.إنه مضمون.

يحرر: وجدت للتو الحل في رأسي:قم بتغيير قاعدة في Makefile لإضافة "-include" CFILES_REGISTER.H "إلى كل" g ++ file.cpp ".

%.o : %.cpp
    $(CC) -include 'cfiles_register.h' -o $@ $<

ضع اقتراحك في تطبيق السؤال على "cfiles_register.h".

وعن طريق حالات ثابتة في C ++ سوف تعمل بشكل جيد.

هل يمكن أن تفعل هذا أيضا في C، ولكن تحتاج إلى استخدام وقت ميزات محددة - لMSVC CRT نلقي نظرة على الموقع http://www.codeguru.com/cpp/misc/misc/threadsprocesses/article.php/c6945/

لC - يمكنك أن تفعل ذلك مع ماكرو - تعريف متغير اسمه الموافق الملف الخاص بك، وبعد ذلك يمكن مسح رموز للتنفيذ الخاص بك، تماما كما فكرة:

 #define TRACK_FILE(name) char _file_tracker_##name;

واستخدامه في my_c_file.c الخاصة بك مثل هذا:

 TRACK_FILE(my_c_file_c)

وومن البقرى كل ملف / أسماء المتغيرات من ثنائي مثل هذا

nm my-binary | grep _file_tracker

وليس لطيفا حقا، ولكن ...

والفكرة الرهيبة، وأنا متأكد، ولكن استخدام المفرد. وعلى كل ملف تفعل شيئا مثل

  Singleton.register(__FILE__); 

وعلى النطاق العالمي. انها سوف تعمل فقط على ملفات حزب الشعب الكمبودي بالرغم من ذلك. فعلت شيئا مثل هذا منذ سنوات كما مبتدئا، وأنه يعمل. ولكن أود أن تذلل للقيام بذلك الآن. فما استقاموا لكم فاستقيموا إضافة خطوة بناء الآن.

وأنا أتفق مع الذين يقولون أنه من الأفضل لتجنب القيام بذلك في وقت التشغيل، ولكن في C، يمكنك تهيئة متغير ثابت مع استدعاء دالة، وهذا هو، في كل ملف:

static int doesntmatter = register( __FILE__);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top