تحذير برنامج التحويل البرمجي (المستوى 2) C4412

رسالة خطأ

'الداله': توقيع دالة تحتوي على نوع 'نوع'؛ تكون غير آمنة الالكائنات C + + إلى يمر ما بين تعليمات برمجية خالصة ومختلط أو الأصلي.

المحول البرمجي بالكشف عن حالة غير آمنة المحتملة التي قد تؤدي في خطأ وقت تشغيل: مكالمة هو يتم إجراؤها من /clr:purecompiland لإحدى الدالات التي تم استيرادها عبر dllimport وتوقيع دالة يحتوي على نوع غير آمن. نوع هو غير آمن إذا أنه يحتوي على وظيفة خاصة بالعضو أو عضو بيانات التي هو على نوع غير آمن أو indirection إلى نوع غير آمن.

Th هو هو غير آمن نظراً للاختلاف استدعاء اصطلاحات بين تعليمات برمجية خالص وأصلية بشكل افتراضي (أو مختلط الأصلي والتي تتم إدارتها). عند استيراد (عن طريق dllimport) دالة في إلى /clr:purecompiland، تأكد من تطابق تصريحات لكل نوع من أنواع توقيع إلى في compiland التي يصدرها الدالة (يتم حريصا خاصة الاختلافات في الاصطلاحات استدعاء ضمني).

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

لمزيد من المعلومات حول /clr:pure راجع كيفية: ترحيل /clr: خالص.

C4412 هو قيد إيقاف التشغيل بشكل افتراضي. لمزيد من المعلومات، راجع Compiler Warnings That Are Off by Default و dllexport, dllimport .

إلى حل هذا التحذير، إزالة الجميع وظائف من النوع.

مثال

إنشاء نموذج التالي C4412.

// C4412.cpp
// compile with: /c /W2 /clr:pure
#pragma warning (default : 4412)

struct Unsafe {
   virtual void __cdecl Test();
};

struct Safe {
   int i;
};

__declspec(dllimport) Unsafe * __cdecl func();
__declspec(dllimport) Safe * __cdecl func2();

int main() {
   Unsafe *pUnsafe = func();   // C4412
   // pUnsafe->Test();

   Safe *pSafe = func2();   // OK
}

نموذج التالي هو ملف عنوان الذي يقوم بتعريف الثاني أنواع. Unsafeنوع هو غير آمن لأنه يحتوي على دالة العضو.

// C4412.h
struct Unsafe {
   // will be __clrcall if #included in pure compilation
   // defaults to __cdecl in native or mixed mode compilation
   virtual void Test(int * pi);

   // try the following line instead
   // virtual void __cdecl Test(int * pi);
};

struct Safe {
   int i;
};

وهذا نموذج تصدير الدالات ذات الأنواع المعرفة في ملف الرأس.

// C4412_2.cpp
// compile with: /LD
#include "C4412.h"

void Unsafe::Test(int * pi) {
   *pi++;
}

__declspec(dllexport) Unsafe * __cdecl func() { return new Unsafe; }
__declspec(dllexport) Safe * __cdecl func2() { return new Safe; }

الافتراضي اصطلاح في /clr:pureالتحويل البرمجي هو مختلفة عن التصنيف الأصلي. عند C4412.h هو مضمنة، Testسيكون بشكل افتراضي __clrcall. إذا قمت بالتحويل البرمجي لتشغيل هذا البرنامج (هل لا استخدم /c)، سوف يقوم البرنامج بطرح على ‏‏ استثناء.

إنشاء نموذج التالي C4412.

// C4412_3.cpp
// compile with: /W2 /clr:pure /c /link C4412_2.lib
#pragma warning (default : 4412)
#include "C4412.h"

__declspec(dllimport) Unsafe * __cdecl func();
__declspec(dllimport) Safe * __cdecl func2();

int main() {
   int n = 7;
   Unsafe *pUnsafe = func();   // C4412
   pUnsafe->Test(&n);

   Safe *pSafe = func2();   // OK
}