وسيطات سطر أوامر الوصول دون استخدام char ** argv في Main

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

  •  20-09-2019
  •  | 
  •  

سؤال

هل هناك أي طريقة للوصول إلى وسيطات سطر الأوامر ، دون استخدام الوسيطة إلى الرئيسية؟ أحتاج إلى الوصول إليها في وظيفة أخرى ، وأفضل عدم تمريرها.

أحتاج إلى حل يعمل بالضرورة على Mac OS و Linux مع GCC.

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

المحلول

لا أعتقد أنه يجب عليك القيام بذلك لأن وقت التشغيل C سيقوم بإعداد الحجج وينقلها إلى الرئيسي عبر int argc, char **argv, ، لا تحاول التعامل مع السلوك عن طريق اختراقه لأنه سيكون غير قابل للمواعيد أو ربما غير محدد إلى حد كبير !! التزم بالقواعد وسيكون لديك قابلية للنقل ... لا توجد طريقة أخرى للقيام بذلك بخلاف كسرها ...

نصائح أخرى

لا أعرف كيف أفعل ذلك على MacOS ، لكنني أظن أن الخدعة التي سأصفها هنا يمكن نقلها إلى MacOS مع القليل من القراءة.

على Linux ، يمكنك استخدام ما يسمى ".init_array" في قسم ELF Binary ، لتسجيل وظيفة يتم استدعاؤها أثناء بدء تشغيل البرنامج (قبل Main (). هذه الوظيفة لها نفس توقيع الوظيفة الرئيسية () العادية ، وإعادة إرجاعها "void". وبالتالي ، يمكنك استخدام هذه الوظيفة لتذكر أو معالجة ArgC و Argv [] و EVP [].

إليك بعض التعليمات البرمجية التي يمكنك استخدامها:

static void my_cool_main(int argc, char* argv[], char* envp[])
{
    // your code goes here
}

__attribute__((section(".init_array"))) void (* p_my_cool_main)(int,char*[],char*[]) = &my_cool_main;

ملاحظة: يمكن أيضًا وضع هذا الرمز في مكتبة ، لذلك يجب أن يناسب قضيتك. حتى أنه يعمل ، عندما يتم تشغيل prgram الخاص بك باستخدام Valgrind - لا يتخلى Valgrind عملية جديدة ، وهذا ينتج عنه/proc/self/cmdline يوضح خط الأوامر Valgrind الأصلي.

PPS: ضع في اعتبارك أنه خلال تنفيذ البرنامج المبكر للغاية ، لم يتم تهيئة العديد من النظام الفرعي بالكامل بعد - لقد جربت إجراءات I/O LIBC ، ويبدو أنها تعمل ، لكن لا تعتمد عليها - حتى متغيرات gloval قد لا يتم بناؤها بعد ، إلخ...

يمكنك نسخها إلى متغيرات عالمية إذا أردت.

في Linux ، يمكنك فتح /proc/self/cmdline (افترض أن /proc موجود) وحاجز يدويًا (هذا مطلوب فقط إذا كنت بحاجة إلى ArgC/argv قبل main() - على سبيل المثال في مُنشئ عالمي - خلاف ذلك ، من الأفضل تمريرها عبر Vars العالمي).

المزيد من الحلول متوفرة هنا: http://blog.linuxgamepublishing.com/2009/10/12/argv-and-argc-and-just-how-to-them/

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

تستطيع. توفر معظم المنصات المتغيرات العالمية __ARGC و __ARGV. لكن مرة أخرى ، أؤيد تعليق Zneak.

PS استخدم Boost :: Program_options لتحليلها. من فضلك لا تفعل ذلك بأي طريقة أخرى في C ++.

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

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top