This documentation is archived and is not being maintained.

Producing Verifiable Components with Managed Extensions for C++

Visual Studio .NET 2003

In Visual Studio .NET 2003, you can generate verifiable components built with Managed Extensions for C++.

Currently, the compiler does not generate any warnings if you include nonverifiable constructs in source code.

The following guidelines will help you author components that can be compiled into a verifiable component:

  • Only fully managed constructs (not unmanaged classes, unmanaged pointers, and unmanaged arrays) are used
  • Global variables are not used.
  • CRT functions are not used and no links are made to unmanaged libraries.
  • A verifiable function may not declare, create, or manipulate any object of unmanaged class type (including simple PODs).
  • A verifiable function may not declare, create, or manipulate any unmanaged pointer.
  • A verifiable function shall not contain a static_cast for down-casting (the compiler changes C-style casts to __try_cast in this case). static_cast between primitive types, like a single into a double, or a Byte into an Int16, is verifiable.
  • A verifiable function shall not contain a reinterpret_cast (or any C-style cast equivalent).
  • A verifiable function shall perform no arithmetic on a interior __gc* (byref) pointer. It may only assign to it and dereference it.
  • A verifiable function shall only throw or catch pointers to __gc classes (hence value types must be boxed before throwing).
  • A verifiable function may only call verifiable functions (such that calls to the CRT are not allowed, include AtEntry/AtExit, and so global constructors are disallowed).
  • The type of a verifiable data member shall be primitive type, verifiable value class type, or a pointer to verifiable gc class type.
  • A verifiable class may only consist of verifiable member functions, and verifiable data members.
  • A verifiable class may not use LayoutKind::Explicit.
  • If building an .exe, a main function cannot declare any parameters; use System::Environment::GetCommandLineArgs.
  • Do not use compiler optimizations.

Also, the following keywords cannot be used in verifiable code:

Compiling a Verifiable Managed Extensions Assembly

This section discusses how to get the Visual C++ compiler to produce a verifiable assembly.

  • Include the following in one of the source files to be compiled:
    #ifdef __cplusplus
    extern "C" { 
    int _fltused=1; 
    void _cdecl _check_commonlanguageruntime_version(){}
    #ifdef __cplusplus
    // An empty data section causes verifier to complain

_check_commonlanguageruntime_version is a CRT internal function to determine the version of the common language runtime. In a pure MSIL image (no native code), you need to override the CRT default behavior, which only allows an image to run on version 1.1 (or later) of the runtime.

  • Specify /clr:initialAppDomain /Od to generate MSIL and disable compiler optimizations
  • Suppress SkipVerification by adding the following attribute to one of your source code files:
    using namespace System::Security::Permissions;
    SecurityAction::RequestMinimum, SkipVerification=false)];
  • Specify linker options /link /dll /noentry /fixed:no /opt:ref, which specify linking to a DLL, a empty main entry point, to generate a relocation section, and remove unused references. Use /entry:main to build an exe.
  • Run SetILOnly.exe on your component. See SetILOnly to access the source code to build this .exe.
  • Use PEVerify to validate if the output image is verifiable.

When building from the development environments, you may want to use a custom build step or build event to run SetILOnly or PEVerify. For more information, see Understanding Custom Build Steps and Build Events.

See Also

Interoperability in Managed Extensions for C++