int ExecuteManagedAssembly( const char* currentExeAbsolutePath, const char* clrFilesAbsolutePath, const char* managedAssemblyAbsolutePath, int managedAssemblyArgc, const char** managedAssemblyArgv) { // Indicates failure int exitCode = -1; std::string coreClrDllPath(clrFilesAbsolutePath); coreClrDllPath.append("/"); coreClrDllPath.append(coreClrDll); if (coreClrDllPath.length() >= PATH_MAX) { fprintf(stderr, "Absolute path to libcoreclr.so too long\n"); return -1; } // Get just the path component of the managed assembly path std::string appPath; GetDirectory(managedAssemblyAbsolutePath, appPath); // Construct native search directory paths std::string nativeDllSearchDirs(appPath); char *coreLibraries = getenv("CORE_LIBRARIES"); if (coreLibraries) { nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(coreLibraries); } nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(clrFilesAbsolutePath); std::string tpaList; AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList); void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL); if (coreclrLib != nullptr) { coreclr_initialize_ptr initializeCoreCLR = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize"); coreclr_execute_assembly_ptr executeAssembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly"); coreclr_shutdown_ptr shutdownCoreCLR = (coreclr_shutdown_ptr)dlsym(coreclrLib, "coreclr_shutdown"); if (initializeCoreCLR == nullptr) { fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n"); } else if (executeAssembly == nullptr) { fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n"); } else if (shutdownCoreCLR == nullptr) { fprintf(stderr, "Function coreclr_shutdown not found in the libcoreclr.so\n"); } else { // Check whether we are enabling server GC (off by default) const char* useServerGc = std::getenv(serverGcVar); if (useServerGc == nullptr) { useServerGc = "0"; } // CoreCLR expects strings "true" and "false" instead of "1" and "0". useServerGc = std::strcmp(useServerGc, "1") == 0 ? "true" : "false"; // Allowed property names: // APPBASE // - The base path of the application from which the exe and other assemblies will be loaded // // TRUSTED_PLATFORM_ASSEMBLIES // - The list of complete paths to each of the fully trusted assemblies // // APP_PATHS // - The list of paths which will be probed by the assembly loader // // APP_NI_PATHS // - The list of additional paths that the assembly loader will probe for ngen images // // NATIVE_DLL_SEARCH_DIRECTORIES // - The list of paths that will be probed for native DLLs called by PInvoke // const char *propertyKeys[] = { "TRUSTED_PLATFORM_ASSEMBLIES", "APP_PATHS", "APP_NI_PATHS", "NATIVE_DLL_SEARCH_DIRECTORIES", "AppDomainCompatSwitch", "System.GC.Server", }; const char *propertyValues[] = { // TRUSTED_PLATFORM_ASSEMBLIES tpaList.c_str(), // APP_PATHS appPath.c_str(), // APP_NI_PATHS appPath.c_str(), // NATIVE_DLL_SEARCH_DIRECTORIES nativeDllSearchDirs.c_str(), // AppDomainCompatSwitch "UseLatestBehaviorWhenTFMNotSpecified", // System.GC.Server useServerGc, }; void* hostHandle; unsigned int domainId; int st = initializeCoreCLR( currentExeAbsolutePath, "unixcorerun", sizeof(propertyKeys) / sizeof(propertyKeys[0]), propertyKeys, propertyValues, &hostHandle, &domainId); if (!SUCCEEDED(st)) { fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st); exitCode = -1; } else { st = executeAssembly( hostHandle, domainId, managedAssemblyArgc, managedAssemblyArgv, managedAssemblyAbsolutePath, (unsigned int*)&exitCode); if (!SUCCEEDED(st)) { fprintf(stderr, "coreclr_execute_assembly failed - status: 0x%08x\n", st); exitCode = -1; } st = shutdownCoreCLR(hostHandle, domainId); if (!SUCCEEDED(st)) { fprintf(stderr, "coreclr_shutdown failed - status: 0x%08x\n", st); exitCode = -1; } } } if (dlclose(coreclrLib) != 0) { fprintf(stderr, "Warning - dlclose failed\n"); } } else { char* error = dlerror(); fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error); } return exitCode; }
int initializeCoreCLR(const char* exePath, const char* appDomainFriendlyName, int propertyCount, const char* mergedPropertyKeys, const char* mergedPropertyValues, const char* managedAssemblyAbsolutePath, const char* clrFilesAbsolutePath) { printf("initializeCoreCLR()\n"); std::string coreClrDllPath(clrFilesAbsolutePath); coreClrDllPath.append("/"); coreClrDllPath.append(coreClrDll); if (coreClrDllPath.length() >= PATH_MAX) { fprintf(stderr, "Absolute path to libcoreclr.so too long\n"); } std::string appPath; if( managedAssemblyAbsolutePath[0] == '\0' ) { printf("Expecting to run a standard .exe\n"); } else { printf("Expecting to load an assembly and invoke arbitrary methods.\n"); GetDirectory(managedAssemblyAbsolutePath, appPath); }; // Construct native search directory paths std::string nativeDllSearchDirs(appPath); char *coreLibraries = getenv("CORE_LIBRARIES"); if (coreLibraries) { nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(coreLibraries); } nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(clrFilesAbsolutePath); std::string tpaList; AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList); coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL); if (coreclrLib != nullptr) { initialize_core_clr = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize"); execute_assembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly"); shutdown_core_clr= (coreclr_shutdown_ptr)dlsym(coreclrLib, "coreclr_shutdown"); create_delegate = (coreclr_create_delegate_ptr)dlsym(coreclrLib, "coreclr_create_delegate"); if (initialize_core_clr == nullptr) { fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n"); return -1; } else if (execute_assembly == nullptr) { fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n"); return -1; } else if (shutdown_core_clr == nullptr) { fprintf(stderr, "Function coreclr_shutdown not found in the libcoreclr.so\n"); return -1; } else { if(useServerGc == NULL) { std::getenv(serverGcVar); if (useServerGc == nullptr) { useServerGc = "0"; } } useServerGc = std::strcmp(useServerGc, "1") == 0 ? "true" : "false"; char *keys[propertyCount]; char *values[propertyCount]; parseValues(mergedPropertyKeys, keys, propertyCount); parseValues(mergedPropertyValues, values, propertyCount); int st = initialize_core_clr( exePath, appDomainFriendlyName, propertyCount, (const char**)keys, (const char**)values, &hostHandle, &domainId); if (SUCCEEDED(st)) { printf("coreclr_initialize ok\n"); } else { fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st); }; } } return 0; }
int ExecuteManagedAssembly( const char* currentExeAbsolutePath, const char* clrFilesAbsolutePath, const char* managedAssemblyAbsolutePath, int managedAssemblyArgc, const char** managedAssemblyArgv) { // Indicates failure int exitCode = -1; std::string coreClrDllPath(clrFilesAbsolutePath); coreClrDllPath.append("/"); coreClrDllPath.append(coreClrDll); if (coreClrDllPath.length() >= PATH_MAX) { fprintf(stderr, "Absolute path to libcoreclr.so too long\n"); return -1; } // Get just the path component of the managed assembly path std::string appPath; GetDirectory(managedAssemblyAbsolutePath, appPath); std::string nativeDllSearchDirs(appPath); nativeDllSearchDirs.append(":"); nativeDllSearchDirs.append(clrFilesAbsolutePath); std::string tpaList; AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList); void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL); if (coreclrLib != nullptr) { ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly"); if (executeAssembly != nullptr) { // Allowed property names: // APPBASE // - The base path of the application from which the exe and other assemblies will be loaded // // TRUSTED_PLATFORM_ASSEMBLIES // - The list of complete paths to each of the fully trusted assemblies // // APP_PATHS // - The list of paths which will be probed by the assembly loader // // APP_NI_PATHS // - The list of additional paths that the assembly loader will probe for ngen images // // NATIVE_DLL_SEARCH_DIRECTORIES // - The list of paths that will be probed for native DLLs called by PInvoke // const char *propertyKeys[] = { "TRUSTED_PLATFORM_ASSEMBLIES", "APP_PATHS", "APP_NI_PATHS", "NATIVE_DLL_SEARCH_DIRECTORIES", "AppDomainCompatSwitch" }; const char *propertyValues[] = { // TRUSTED_PLATFORM_ASSEMBLIES tpaList.c_str(), // APP_PATHS appPath.c_str(), // APP_NI_PATHS appPath.c_str(), // NATIVE_DLL_SEARCH_DIRECTORIES nativeDllSearchDirs.c_str(), // AppDomainCompatSwitch "UseLatestBehaviorWhenTFMNotSpecified" }; HRESULT st = executeAssembly( currentExeAbsolutePath, coreClrDllPath.c_str(), "unixcorerun", sizeof(propertyKeys) / sizeof(propertyKeys[0]), propertyKeys, propertyValues, managedAssemblyArgc, managedAssemblyArgv, managedAssemblyAbsolutePath, NULL, NULL, NULL, (DWORD*)&exitCode); if (!SUCCEEDED(st)) { fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st); exitCode = -1; } } else { fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n"); } if (dlclose(coreclrLib) != 0) { fprintf(stderr, "Warning - dlclose failed\n"); } } else { char* error = dlerror(); fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error); } return exitCode; }