سؤال

لدي DLL الذي يحتاج إلى الوصول إلى البيانات المخزنة في حاويات STL في تطبيق المضيف. نظرا لأن C ++ لا يوجد لديه قياسي ABI، وأريد دعم التحويل البرمجيات المختلفة، والواجهة بين التطبيق و DLL يجب أن تظل أساسا بيانات قديمة عادية.

بالنسبة للنظارات هذه واضحة نسبيا. يمكنك ببساطة إرجاع كتلة الذاكرة من المتجه، لأنه مضمون أن تكون غاية

// To return vector<int> data
virtual void GetVectorData(const int*& ptr, size_t& count) const
{
    if (!vec.empty())
        ptr = &(vec.front());

    count = vec.size();
}

الآن يمكن أن يكون DLL الوصول الآمن للقراءة فقط إلى بيانات متجه عبر تلك الواجهة. يمكن ل DLL أيضا التفاف هذا لنسخ المحتويات إلى متجه لنفسه أيضا.

ماذا عن قوائم STL (والانتعانات) على الرغم من؟ هل هناك طريقة أخرى واضحة للسماح بالوصول عبر حدود DLL؟ أو هل يجب علي اللجوء إلى واجهة نوع من getFirst () / getnext ()؟ قد أحتاج إلى القيام بذلك للحصول على الكثير من القوائم، لذلك سيكون من الجيد أن يكون لديك حل بسيط مثل المتجهات.

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

المحلول

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

ListHandle lhi = GetListDataBegin();
const ListHandle lhe = GetListDataEnd();

while (lhi != lhe)
{
  int value = GetListItem(lhi);
  ...
  lhi = GetNextListItem(lhi);
}

نصائح أخرى

يمكنك تمرير كائنات STL بين DLLs ودعم المحامرة المختلفة إذا كنت حذرا حيث تقوم بإنشاء إنشاء كل نوع من نوع STL. تحتاج إلى بعض وحدات ماكروس ذكية "DLExport" - يمكنني استخدام المجموعة التالية لدعم VC و GCC بنجاح بنجاح.

#ifdef WIN32
#ifdef MYDLLLIB_EXPORTS      // DLL export macros
#define MYDLLLIB_API __declspec(dllexport)
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_API __declspec(dllimport)
#define MYDLLLIB_TEMPLATE extern
#endif
#else                       // Not windows --- probably *nix/bsd
#define MYDLLLIB_API
#ifdef MYDLLLIB_EXPORTS
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_TEMPLATE extern
#endif
#endif // WIN32

عند تجميع DLL، حدد MyDllLib_Exports. في DLL، يمكنك إذن إنشاء كل نوع من النوع STL الذي ترغب في استخدامه، على سبيل المثال، قوائم أو متجهات من الأوتار

MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::vector<std::string>;
MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::list<std::string>;

سوف يرى المستهلكون في DLL (الذين ليس لديهم mydlllib_exports)

extern template class __declspec(dllimport) std::vector<std::string>;

واستخدام التعليمات البرمجية الثنائية المصدرة من DLL بدلا من Instantiating خاصة بهم.

يجب أن تظل الواجهة بين التطبيق و DLL أساسا بيانات قديمة عادية.

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

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

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