كيفية استخدام فئة مصدرة (__declspec (dllexport)) في قالب STL؟

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

  •  27-09-2019
  •  | 
  •  

سؤال

أنا أستخدم فئة مصدرة

class __declspec(dllexport) myclass  
{  
private:  
template __declspec(dllexport) class std::map<myclass*,int>;    
std::map<myclass*,int>m_map;  
//something  
};    

عندما أفعل ذلك ، أحصل على تحذير C4251 قائلاً M_MAP: يحتاج الفصل الدراسي "Std :: Map <_kty ، _ty> إلى الحصول على واجهة DLL لاستخدامها من قبل عملاء الفئة MyClass.
أي أفكار حول كيف يمكنني حل هذا؟
أتول

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

المحلول

يجب ألا تستخدم __declspec (dllexport) في ملفات الرأس التي ستستخدمها رمز استخدام DLL الخاص بك ، حيث يجب أن تستخدم __declspec (dllimport).

لذلك يجب عليك إنشاء ماكرو يستخدم dllexport إذا تم تعيين تعريف آخر معين ، و dllimport إذا لم يكن كذلك.

في رأس مشترك في مكان ما:

#ifdef EXPORTING_FOO
#define FOO_API __declspec(dllexport)
#else
#define FOO_API __declspec(dllimport)
#endif

يمكنك إنشاء مثيل لقالب:

extern template class FOO_API Templ<MyClass, int >;

ضمن رأس مشمل. لاحظ الخارجي هنا. ضمن وحدة تجميع واحدة تعلن نفس الشيء ولكن بدون الخارج وبدون foo_api ، وبالتالي:

template class Templ<MyClass, int >;

سيعني هذا أن الكود الذي يستخدم مكتبتك لن ينشئ القالب ولكنه سيستخدم الرمز في مكتبتك. هذا مفيد بشكل خاص عندما يكون لدى القالب أعضاء افتراضيين.

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

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

نصائح أخرى

لم تجربها أبدًا ، ولكن يبدو أن هذا الرابط يبحث في هذه المشكلة:http://support.microsoft.com/kb/168958

لا يمكنك تصدير فصل مع أعضاء لم يتم تصديرهم. سيكون الحل المحتمل هو استخدام المصطلح PIMPL. مع PIMPL ، لا يعرف أعضاء الفصل للمستخدم. لذلك لا تحتاج فصول STL إلى تصدير. لمزيد من القراءة حول Pimpl ، تحقق من ما يلي:http://c2.com/cgi/wiki؟pimplidiom أو http://www.gamedev.net/reference/articles/article1794.asp

مثال:

myclass.h:

class __declspec(dllexport) myclass
{
public:
    myclass();
    virtual ~myclass();
private:
    myclass(const myclass& other) {}
    myclass& operator=(const myclass& rhs) {return *this;}
    myclassImpl* m_Pimpl;
};

myclass.cpp:

#include "myclass.h"
#include "myclassImpl.h"


myclass::myclass()
    :m_Pimpl(new myclassImpl())
{}

myclass::~myclass() {
    delete m_Pimpl;
}

myclassimpl.h:

class myclassImpl {
private:
    std::map<myclass*,int>m_map;
};
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top