Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
"function": сигнатура функции содержит тип "type"; Объекты C++ небезопасны для передачи между чистым кодом и смешанным или собственным кодом.
Замечания
Параметр /clr:pure компилятора устарел в Visual Studio 2015 и не поддерживается, начиная с Visual Studio 2017. Если у вас есть код, который должен быть чистой средой CLR, рекомендуется перенести его в C#.
Компилятор обнаружил потенциально небезопасную ситуацию, которая может привести к ошибке среды выполнения: вызов выполняется из кода, скомпилированного с /clr:pure функцией, импортированной через dllimport, и сигнатура функции содержит небезопасный тип. Тип небезопасн, если он содержит функцию-член или имеет элемент данных, который является небезопасным типом или косвенным для небезопасного типа.
Этот шаблон небезопасн из-за различий в соглашениях о вызовах по умолчанию между чистым и машинным кодом (или смешанным собственным и управляемым). При импорте функции через dllimport в код, скомпилированный с помощью /clr:pure, убедитесь, что объявления каждого типа в сигнатуре идентичны сигнатуре в компилянде, который экспортирует функцию (особенно обращая внимание на различия в неявных соглашениях о вызовах).
Функция виртуального члена особенно подвержена непредвиденным результатам. Однако даже невиртуальная функция должна быть проверена, чтобы убедиться, что вы получите правильные результаты. Это предупреждение можно игнорировать, убедившись, что результат правильный.
По умолчанию C4412 отключен. Для получения более подробной информации см. Предупреждения компилятора, отключенные по умолчанию и dllexport, dllimport.
Чтобы устранить это предупреждение, удалите все функции из типа.
Примеры
В следующем примере создается C4412:
// 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.
В следующем примере создается 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
}