/CLRSUPPORTLASTERROR (Preserve Last Error Code for PInvoke Calls)

 

For the latest documentation on Visual Studio 2017, see Visual Studio 2017 Documentation.

For the latest documentation on Visual Studio 2017, see -CLRSUPPORTLASTERROR (Preserve Last Error Code for PInvoke Calls) on docs.microsoft.com. /CLRSUPPORTLASTERROR, which is on by default, preserves the last error code of functions called through the P/Invoke mechanism, which allows you to call native functions in DLLS, from code compiled with /clr.

/CLRSUPPORTLASTERROR{:NO | SYSTEMDLL}  

Preserving the last error code implies a decrease in performance. If you do not want to incur the performance impact of preserving the last error code, link with /CLRSUPPORTLASTERROR:NO.

You can minimize the performance impact by linking with /CLRSUPPORTLASTERROR:SYSTEMDLL, which only preserves the last error code for functions in system DLLs. A system DLL is defined as one of the following:

ACLUI.DLLACTIVEDS.DLLADPTIF.DLLADVAPI32.DLL
ASYCFILT.DLLAUTHZ.DLLAVICAP32.DLLAVIFIL32.DLL
CABINET.DLLCLUSAPI.DLLCOMCTL32.DLLCOMDLG32.DLL
COMSVCS.DLLCREDUI.DLLCRYPT32.DLLCRYPTNET.DLL
CRYPTUI.DLLD3D8THK.DLLDBGENG.DLLDBGHELP.DLL
DCIMAN32.DLLDNSAPI.DLLDSPROP.DLLDSUIEXT.DLL
GDI32.DLLGLU32.DLLHLINK.DLLICM32.DLL
IMAGEHLP.DLLIMM32.DLLIPHLPAPI.DLLIPROP.DLL
KERNEL32.DLLKSUSER.DLLLOADPERF.DLLLZ32.DLL
MAPI32.DLLMGMTAPI.DLLMOBSYNC.DLLMPR.DLL
MPRAPI.DLLMQRT.DLLMSACM32.DLLMSCMS.DLL
MSI.DLLMSIMG32.DLLMSRATING.DLLMSTASK.DLL
MSVFW32.DLLMSWSOCK.DLLMTXEX.DLLNDDEAPI.DLL
NETAPI32.DLLNPPTOOLS.DLLNTDSAPI.DLLNTDSBCLI.DLL
NTMSAPI.DLLODBC32.DLLODBCBCP.DLLOLE32.DLL
OLEACC.DLLOLEAUT32.DLLOLEDLG.DLLOPENGL32.DLL
PDH.DLLPOWRPROF.DLLQOSNAME.DLLQUERY.DLL
RASAPI32.DLLRASDLG.DLLRASSAPI.DLLRESUTILS.DLL
RICHED20.DLLRPCNS4.DLLRPCRT4.DLLRTM.DLL
RTUTILS.DLLSCARDDLG.DLLSECUR32.DLLSENSAPI.DLL
SETUPAPI.DLLSFC.DLLSHELL32.DLLSHFOLDER.DLL
SHLWAPI.DLLSISBKUP.DLLSNMPAPI.DLLSRCLIENT.DLL
STI.DLLTAPI32.DLLTRAFFIC.DLLURL.DLL
URLMON.DLLUSER32.DLLUSERENV.DLLUSP10.DLL
UXTHEME.DLLVDMDBG.DLLVERSION.DLLWINFAX.DLL
WINHTTP.DLLWININET.DLLWINMM.DLLWINSCARD.DLL
WINTRUST.DLLWLDAP32.DLLWOW32.DLLWS2_32.DLL
WSNMP32.DLLWSOCK32.DLLWTSAPI32.DLLXOLEHLP.DLL
System_CAPS_ICON_note.jpg Note

Preserving the last error is not supported for unmanaged functions that are consumed by CLR code, in the same module.

To set this linker option in the Visual Studio development environment

  1. Open the project's Property Pages dialog box. For details, see Setting Visual C++ Project Properties.

  2. Click the Linker folder.

  3. Click the Command Line property page.

  4. Type the option into the Additional Options box.

To set this linker option programmatically

The following sample defines a native DLL with one exported function that modifies last error.

// CLRSUPPORTLASTERROR_dll.cpp  
// compile with: /LD  
#include <windows.h>  
#include <math.h>  
  
#pragma unmanaged  
__declspec(dllexport) double MySqrt(__int64 n) {  
   SetLastError(DWORD(-1));  
   return sqrt(double(n));  
}  

The following sample consumes the DLL, demonstrating how to use /CLRSUPPORTLASTERROR.

// CLRSUPPORTLASTERROR_client.cpp  
// compile with: /clr CLRSUPPORTLASTERROR_dll.lib /link /clrsupportlasterror:systemdll  
// processor: x86  
#include <windows.h>  
#include <wininet.h>  
#include <stdio.h>  
#include <math.h>  
  
#pragma comment(lib, "wininet.lib")  
  
double MySqrt(__int64 n);  
  
#pragma managed  
int main() {  
   double   d = 0.0;  
   __int64 n = 65;  
   HANDLE  hGroup = NULL;  
   GROUPID groupID;  
   DWORD   dwSet = 127, dwGet = 37;  
  
   SetLastError(dwSet);  
   d = MySqrt(n);  
   dwGet = GetLastError();  
  
   if (dwGet == DWORD(-1))  
      printf_s("GetLastError for application call succeeded (%d).\n",  
             dwGet);  
   else  
      printf_s("GetLastError for application call failed (%d).\n",  
             dwGet);  
  
   hGroup = FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL,  
                           0, 0, &groupID, 0);  
   dwGet = GetLastError();  
   if (dwGet == 183)  
      printf_s("GetLastError for system call succeeded (%d).\n",  
             dwGet);  
   else  
      printf_s("GetLastError for system call failed (%d).\n",  
             dwGet);  
}  

GetLastError for application call failed (127).  
GetLastError for system call succeeded (183).  

Setting Linker Options
Linker Options

Show: