This article is the sequel to the previous article, this article will continue to introduce the logic inside Coreconsole.cpp. Perhaps people will read some of the CLR's books, I admit I have not seen, because I think a person, he again NB, that is his own vision, and to say the ugly, the CLR is not the person who wrote the book a person to complete the project, so his vision, I personally see, is still very limited.
To undertake the hostenvironment of the previous article, the host environment: the individual considers the host to refer to the Windows kernel. But the CLR has a drawback, is that it is not a cross-platform, so the broad sense that the host should be "operating system kernel"; Let's take a look at loadcoreclr this method, the core purpose of this method is to get the CLR from the dynamic link library, if the error, will be recorded log;
Try to "load" the CoreCLR with a CoreCLR path hmodule tryloadcoreclr (const wchar_t* directorypath) {//coreclr path wchar_t core The clrpath[max_longpath];//assigns the formal parameter to the argument, which is equivalent to coreclrpath= directorypath wcscpy_s (Coreclrpath, directorypath);// Take Coreclrdll,append to the back of CORECLRPATHD and make up a new string wcscat_s (Coreclrpath, Coreclrdll);//Logging start: Attempt to load coreclr *m_lo from the path G << W ("Attempting to load:") << Coreclrpath << Logger::endl;//loadlibraryex mount the specified dynamic-link library. hmodule result =:: Loadlibraryexw (Coreclrpath, NULL, 0);//When loading fails, log if (!result) {*m_log << W ( "Failed to load:") << Coreclrpath << Logger::endl; *m_log << W ("Error Code:") << GetLastError () << Logger::endl; return nullptr; }//Pin The Module-coreclr.dll does not a support being UNLOADED.//GETMODULEHANDLEEXW is a module handle that gets an application or dynamic link library H Module dummy_coreclrmodule;//If it is get_module_handle_ex_flag_pin, then it is mapped in the process that called the function until the process ends if (!::getmodulehandleexw (Get_module_handle_ex_flag_pin, Coreclrpath, &dummy_coreclrmodule)) {*m_log << W ("Failed to pin:") << Coreclrpath << Logger::endl; return nullptr; } wchar_t Coreclrloadedpath[max_longpath]; :: Getmodulefilenamew (Result, Coreclrloadedpath, Max_longpath); *m_log << W ("Loaded:") << Coreclrloadedpath << logger::endl;//return dynamic link library return result; }
The following is the constructor of Hostenvironment, and the main function of the individual is to initialize and load the CORECLR.
Public://path to the directory of that CoreCLR is IN//CORECLR, note the difference between "module path" and this path wchar_t M_coreclrdirectorypath [max_longpath];//the constructor with the log parameter and initialize the log and CLR runtime hostenvironment (Logger *logger): M_log (Logger), M_clrruntimehost ( NULLPTR) {//Discover the path to this EXE ' s module. All other files is expected to being in the same directory.//gets the length of the path of the EXE module in the directory DWORD thismodulelength =:: Getmodul Efilenamew (:: Getmodulehandlew (nullptr), M_hostpath, Max_longpath); Search for the final backslash in the host path.//find the last delimiter in the path "\ \", if found, jump out of the loop int lastbackslashindex; for (Lastbackslashindex = thisModuleLength-1; lastbackslashindex >= 0; lastbackslashindex--) {i F (m_hostpath[lastbackslashindex] = = W (' \ \ ')) {break; }}//Copy the directory path//with M_hostdirectorypath instead of the previous path directory address:: wcsncpy_s (M_hostdirect Orypath, M_hostpath, Lastbackslashindex + 1); Save the EXE name//host the name of the EXE file, similar to the file name, but here I have a question://m_hostpath is a character-type pointer, and lastbackslashindex+1 is a number, put them 2 what is the meaning of adding up? M_hostexename = M_hostpath + lastbackslashindex + 1; *m_log << W ("Host directory:") << M_hostdirectorypath << Logger::endl; Check for%core_root% and try-to-load CoreCLR.dll from the IT if it is set//attempt to load coreclr//coreroot environment variables from the environment variable%core_root% real path wchar_t Coreroot[max_longpath]; size_t outsize;//If the Tryloadcoreclr method is not used, then the constructor is used to initialize coreclr.m_coreclrmodule = NULL; Initialize This here since we don't call tryloadcoreclr if Core_root is unset.//take the value of the environment variable if (_wgetenv_s (& Outsize, Coreroot, Max_longpath, W ("Core_root")) = = 0 && outsize > 0) {wcscat_s (CORE Root, Max_longpath, W ("\ \")); M_coreclrmodule = TRYLOADCORECLR (coreroot); } else {*m_log << W ("Core_root not SEt Skipping ") << Logger::endl; *m_log << W ("You can set the environment variable core_root to point to the path") << Logger::endl; *m_log << W ("where CoreCLR.dll lives to help this executable find it.") << Logger::endl; }//try to load CoreCLR from the directory, the This exexutable is in//try loading CoreCLR from the catalog. if (!m_coreclrmodule) {m_coreclrmodule = TRYLOADCORECLR (M_hostdirectorypath); }//effect Ditto (thismodulelength) if (m_coreclrmodule) {//Save the directory that CoreCLR is found in DWORD modulepathlength =:: Getmodulefilenamew (M_coreclrmodule, M_coreclrdirectorypath, Max_longpath); Search for the last backslash and terminate it there to keep just the directory path with trailing slash for (Lastbackslashindex = modulePathLength-1; lastbackslashindex >= 0; lastbackslashindex--) { if (m_coreclrdirectorypath[lastbackslashindex] = = W (' \ \ ')) {M_CORECLRDIRECTORYPATH[LASTBACKSL Ashindex + 1] = W (' n '); Break }}} else {*m_log << W ("Unable to load") << Coreclrdll << Lo Gger::endl; }}//destructor, releasing CoreCLR ~hostenvironment () {if (m_coreclrmodule) {//Free the module. This is do for completeness, but the fact CoreCLR.dll//was pinned earlier so this call won ' t actually free It. The pinning is//do because CoreCLR does not a support unloading. :: FreeLibrary (M_coreclrmodule); } }
The following is a list of the contents of the TPA to determine whether there are included files, the specific role is unknown.
If each item in the TPA list contains a file, at least one of which contains the file, then return true//filenamewithoutextension: The filename//rgtpaextensions:tpa suffix without the suffix, note that this is a pointer to a pointer. Countextensions: Number of suffixes bool Tpalistcontainsfile (wchar_t* filenamewithoutextension, wchar_t** rgTPAExtensions, int Countextensions) {if (!m_tpalist.cstr ()) return false;//returns the false//loop suffix directly if the assembly path is empty. for (int iextension = 0; iextension < countextensions; iextension++) {wchar_t Filename[max_longpath] ;/So, we don't match other files, and the current file name//does not match the end of the other (compared to the filename) wcscpy_s (Filena Me, Max_longpath, W ("\ \")); wcscat_s function, add the third parameter to the end of the first argument wcscat_s (FileName, Max_longpath, filenamewithoutextension); wcscat_s (FileName, Max_longpath, rgtpaextensions[iextension] + 1); wcscat_s (FileName, Max_longpath, W (";")); So, we don ' t match other files this begin with the current file name//similar to. NET contains if (Wcsstr (M_tpalist.cstr (), fileName) { return true; }} return false; }
The following method is to remove the file suffix, which should be a tool class
Remove file suffix void Removeextensionandni (wchar_t* fileName) { //Remove extension, if it exists//if the file has a suffix, then long removed wchar_t* Extension = WCSRCHR (FileName, W ('. ')); if (extension! = NULL) { extension[0] = W (' n '); Check for. ni//detects. ni files, this kind of file, I did not check the online size_t len = wcslen (fileName); if (Len > 3 && filename[len-1] = = W (' i ') && filename[len-2] = = W (' n ') && fil Ename[len-3] = = W ('. ')) {//end character, equivalent. NET filename[len-3] = W (' substring ');}}}
The following 2 methods are all loading files into tpalist.
Returns the semicolon-separated List of paths to runtime DLLs that is considered trusted. On first calling, scans the CORECLR directory for DLLs and adds them all to the list.//returns a list of trusted and semicolon-delimited lists to the runtime//At the time of the initial call, searching for CO RECLR all DLLs inside the directory and add them to tpalist to go to const wchar_t * Gettpalist () {if (!m_tpalist.cstr ()) {///file suffix collection Wcha r_t *rgtpaextensions[] = {//Probe for. Ni.dll first so it's preferred if NI and il coexist in the same dir// *.ni.dll files, NI and Il will have a priority problem W ("*.ni.dll"), W ("*.dll"), W ("*.ni.exe"), W ("*.exe"),}; Add files from%core_libraries% if specified//loads the file from the%core_libraries% environment variable, if this environment variable is set wchar_t Corelibraries[ma X_longpath]; size_t outsize; if (_wgetenv_s (&outsize, Corelibraries, Max_longpath, W ("core_libraries")) = = = 0 && outsize > 0) {wcscat_s (cOrelibraries, Max_longpath, W ("\ \")); Addfilesfromdirectorytotpalist (Corelibraries, Rgtpaextensions, _countof (rgtpaextensions)); } else {*m_log << W ("Core_libraries not set; Skipping ") << Logger::endl; *m_log << W ("You can set the environment variable core_libraries to point to a") << Logger::endl; *m_log << W ("Path containing additional platform assemblies,") << Logger::endl; }//loading files from the directory into Tpalist addfilesfromdirectorytotpalist (M_coreclrdirectorypath, Rgtpaextensions, _countof (rgTPAExte Nsions)); } return M_tpalist.cstr (); return to Tpalist; }
Today is the point here, the next one with you notice, will be the third introduction of GC to write out ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
C + + essay: The Coreconsole of CORLECLR core exploration of. NET CoreCLR (2)