سؤال

أنا أعمل مع مكتبة تعيد تعريف NULL.يسبب بعض المشاكل مع أجزاء أخرى من برنامجي.لست متأكدًا مما يمكنني فعله حيال ذلك.اي فكرة؟برنامجي بلغة C++، والمكتبة موجودة ج.

#ifdef NULL
#undef NULL
#endif

/**
 * NULL define.
 */
#define NULL    ((void *) 0)

أوه، وتنتج هذه الأخطاء:

Generic.h:67: error: default argument for parameter of type 'LCD::LCDBase*' has type 'void*'
Generic.cpp: In constructor 'LCD::Generic::Generic(std::string, Json::Value*, int, LCD::LCDBase*)':
Generic.cpp:44: error: invalid conversion from 'void*' to 'QObject*'
Generic.cpp:44: error:   initializing argument 2 of 'LCD::LCDWrapper::LCDWrapper(LCD::LCDInterface*, QObject*)'
Generic.cpp: In member function 'void LCD::Generic::BuildLayouts()':
Generic.cpp:202: error: invalid conversion from 'void*' to 'LCD::Widget*'
Generic.cpp: In member function 'void LCD::Generic::AddWidget(std::string, unsigned int, unsigned int, std::string)':
Generic.cpp:459: error: invalid conversion from 'void*' to 'LCD::Widget*'
scons: *** [Generic.o] Error 1

وهنا أول واحد:

Generic(std::string name, Json::Value *config, int type, LCDBase *lcd = NULL);

يحرر:حسنًا، يعمل الإرسال بشكل صريح، ولكن كيف أقوم بالإرسال لمؤشر دالة؟

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

المحلول

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

مشكلتك الآن هي أن لغة C++ لا تسمح بالإرسال التلقائي من void * إلى أنواع المؤشرات الأخرى مثل لغة C.

من مرجع C ++:

في C++، يتم توسيع NULL إما إلى 0 أو 0L.

إذا لم ينجح ذلك، فما عليك سوى إجراء استبدال عام في المكتبة: NULL ل LIBDEFINEDNULL أو شيء ما.بهذه الطريقة ستحافظ على رمز المكتبة سليمًا وتتجنب تصادم الماكرو.

نصائح أخرى

هل لديك حق الوصول إلى مصدر المكتبات هذا؟إذا كان الأمر كذلك، أعتقد أن البحث والاستبدال على الكود الخاص بهم هو أمر سليم.(استبدل NULL بـ LIBNAME_NULL أو شيء مشابه.) إذا لم يكن هذا خيارًا، فأنا أوصي باستخدام 0 في التعليمات البرمجية الخاصة بك بدلاً من NULL.

أنا فضولي، رغم ذلك:ما هي المشاكل التي يسببها ذلك؟إنهم لا يغيرون قيمة القيمة الفارغة، بل يغيرون القيمة الافتراضية فقط.

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

ستحدد الكثير من التطبيقات NULL مثل هذا:

#undef NULL

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif

هذا لأنه في لغة C، من المنطقي أن يكون مؤشرًا فارغًا، لأنه نوع مؤشر يمكن تحويله ضمنيًا إلى أنواع أخرى.

لا يسمح C++ بهذا (والذي يسبب مشاكلك)، ولكن باستخدام 0 بدلاً من NULL يعمل.

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

سيكون النهج الأكثر عمومية هو إنهاء المخالفة التي تتضمن و محل و يعيد التعريف السابق لوحدات الماكرو.ومع ذلك، هذا يعتمد على المترجم.
هذه هي الطريقة التي يمكنك القيام بها باستخدام VC:

#pragma push_macro("NULL")
#include <offendinglib.h>
#pragma pop_macro("NULL")

وبدلاً من ذلك، قم بتعيين الماكرو على ما تريده بعد ذلك:

#include <offendinglib.h>
#undef NULL
#define NULL 0

نعم، كل ما عليك فعله هو الإلقاء بشكل مناسب:

Generic(std::string name, Json::Value *config, int type,
    LCDBase *lcd = (LCDBase *)NULL);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top