سؤال

لدي الرمز التالي:

std::string F()
{
  WideString ws = GetMyWideString();

  std::string ret;
  StringUtils::ConvertWideStringToUTF8(ws, ret);
  return ret;
}

WideString هو فئة من طرف ثالث ، لذلك هي StringUtils. هم صندوق أسود بالنسبة لي. يتم تمرير المعلمة الثانية بالرجوع إليها.

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

ماذا يمكن أن تفعل وظيفة التحويل للتسبب في هذا؟ أي أفكار لإصلاحها؟

تحديث:

  • المشروع نفسه هو DLL
  • StringUtils هو lib
  • تم تجميع المشروع ضد CRT Multithed (وليس تصحيح ، وليس DLL)
  • يبدو أن البرنامج يعمل بشكل جيد عند الركض خارج Visual Studio
هل كانت مفيدة؟

المحلول

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

نصائح أخرى

صمم مصمم StringUtils واجهة برمجة تطبيقات سيئة للغاية. لا ينبغي استخدام أي من أنواع المكتبات القياسية المُقيّمة في الواجهة العامة لـ API. std::string تم تفجيرها. لذا ، إذا لم يكن برنامج التحويل البرمجي والمكتبات الذي تستخدمه هو نفس المترجم والمكتبات المستخدمة من قبل تطبيق StringUtils ، فستكون الأنواع مختلفة ومن المحتمل أن تكون مختلفة. في الأساس ، تطبيق StringUtils فشل في فصل الواجهة عن التنفيذ.

توضيح للمشكلة. لنفترض أنك تستخدم MSVC 9.0 SP1 وأنا أستخدم MSVC 8.0. في المترجم الخاص بي ، قد يبدو تنفيذ Std :: String هكذا:

class string
{
// : :  stuff
private:
  int someInt_;
  char* someBuf_;
};

... ولكن على المترجم الخاص بك قد يبدو مختلفًا:

class string
{
// : :  stuff
private: 

  void* impl_;
};

إذا كتبت وظيفة مكتبة:

void DoSomethingWithAString(std::string& str);

... وتسميها ، sizeof(string) في الكود الخاص بك سيكون مختلفا عن sizeof(string) في الكود الخاص بي. الأنواع ليست هي نفسها.

لديك حقًا حللين لمشكلتك:

1) [المفضل] احصل على تطبيق StringUtils لإصلاح رمزه المكسور.

2) استبدل المكتبة المستخدمة من قبل المترجم الخاص بك لمطابقة المكتبة المستخدمة بواسطة تطبيق StringUtil. قد تكون قادرًا على تحقيق ذلك باستخدام نفس المترجم في نفس مستوى التصحيح الذي يستخدمه المنفذ ، على افتراض أنه لم يحل محل تنفيذ المكتبة القياسية.

تحرير: 3) سيكون الخيار الثالث هو التوقف عن استخدام StringUtils. بصراحة هذا ربما ما أفعله.

من الرمز الصغير الذي تظهره ، أفترض StringUtils::ConvertWideStringToUTF8() يأخذ std::string& كمعلمة ثانية. بالنظر إلى ذلك ، لا أرى كيف يمكن أن يسبب الرمز الخاص بك فسادًا.

لاحظ ، مع ذلك ، أن ربط مكتبات C ++ بشكل عام لا يعمل إلا عندما تم تجميع الرمز باستخدام نفس المترجم ونفس إعدادات التحويل البرمجي.

استخدامك ل StringUtils و WideString يجعل الأمر يبدو أنك تستخدم C ++ Builder. هل تحاول خلط وحدة منشئ C ++ ووحدة C ++ المرئية؟ إذا كان الأمر كذلك ، فسترى بالتأكيد المشكلات التي وصفتها.

لا يمكنك تمرير مرئي C ++ std::string إلى دالة منشئ C ++ لأن رمز منشئ C ++ سوف يفترض أن المعلمة تستخدم C ++ Builder's std::string تعريف. قد تحتوي الفصول على حقول مختلفة ، وقد تكون الحقول المشتركة التي تشترك فيها في ترتيب مختلف.

حتى إذا كانت الفئات لديها نفس التعريفات ، فستظل الوحدات تستخدم مديري الذاكرة المختلفين. ستخصص الوظيفة المدعومة ذاكرة لمحتويات السلسلة الجديدة باستخدام مدير الذاكرة الخاص بها ، وسيستخدم المتصل مدير الذاكرة الخاص به لمحاولة تحرير محتويات السلسلة لاحقًا.

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