2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 #include "dotnet_launcher.h"
31 namespace dotnetcore {
33 CoreRuntime::CoreRuntime() :
34 InitializeClr(nullptr),
35 ExecuteAssembly(nullptr),
37 CreateDelegate(nullptr),
41 PreparedFunction(nullptr),
42 LaunchFunction(nullptr)
45 #define __STR(x) __XSTR(x)
48 DeviceAPIDirectory = __STR(DEVICE_API_DIR);
51 RuntimeDirectory = __STR(RUNTIME_DIR);
54 NativeLibDirectory = __STR(NATIVE_LIB_DIR);
57 #ifdef USE_MANAGED_LAUNCHER
58 #ifdef CORECLR_LAUNCHER_ASSEMBLY_PATH
59 LauncherAssembly = __STR(CORECLR_LAUNCHER_ASSEMBLY_PATH);
66 _DBG("Constructor called!!");
69 CoreRuntime::~CoreRuntime()
74 int CoreRuntime::Initialize(bool standalone)
78 const char *_deviceapi_directory = getenv("DeviceAPIDirectory");
79 const char *_runtime_directory = getenv("RuntimeDirectory");
80 if (_deviceapi_directory != nullptr)
81 DeviceAPIDirectory = _deviceapi_directory;
82 if (_runtime_directory != nullptr)
83 RuntimeDirectory = _runtime_directory;
85 #ifdef USE_MANAGED_LAUNCHER
86 const char *_launcher_assembly = getenv("LauncherAssembly");
87 if (_launcher_assembly != nullptr)
88 LauncherAssembly = _launcher_assembly;
92 if (DeviceAPIDirectory.empty())
94 _ERR("Empty Device API Directory");
99 DeviceAPIDirectory = AbsolutePath(DeviceAPIDirectory);
102 if (RuntimeDirectory.empty())
104 _ERR("Empty Runtime Directory");
109 RuntimeDirectory = AbsolutePath(RuntimeDirectory);
112 #ifdef USE_MANAGED_LAUNCHER
113 if (LauncherAssembly.empty())
115 _ERR("Empty Launcher Assembly");
120 LauncherAssembly = AbsolutePath(LauncherAssembly);
124 std::string libcoreclr(ConcatPath(RuntimeDirectory, "libcoreclr.so"));
126 _DBG("libcoreclr : %s", libcoreclr.c_str());
128 coreclrLib = dlopen(libcoreclr.c_str(), RTLD_NOW | RTLD_LOCAL);
129 if (coreclrLib == nullptr)
131 char *err = dlerror();
132 _ERR("dlopen failed to open libcoreclr.so with error %s", err);
136 #define CORELIB_RETURN_IF_NOSYM(type, variable, name) \
137 do { variable = (type)dlsym(coreclrLib, name); \
138 if (variable == nullptr) { \
139 _ERR(name " is not found in the libcoreclr.so"); \
143 CORELIB_RETURN_IF_NOSYM(coreclr_initialize_ptr, InitializeClr, "coreclr_initialize");
144 CORELIB_RETURN_IF_NOSYM(coreclr_execute_assembly_ptr, ExecuteAssembly, "coreclr_execute_assembly");
145 CORELIB_RETURN_IF_NOSYM(coreclr_shutdown_ptr, Shutdown, "coreclr_shutdown");
146 CORELIB_RETURN_IF_NOSYM(coreclr_create_delegate_ptr, CreateDelegate, "coreclr_create_delegate");
148 #undef CORELIB_RETURN_IF_NOSYM
150 _DBG("libcoreclr dlopen and dlsym success");
152 _DBG("this addr : %x", this);
153 _DBG("coreclr_initialize : %x", InitializeClr);
158 bool CoreRuntime::InitializeCoreClr(const char* app_id,
159 const char* assembly_probe_paths,
160 const char* pinvoke_probe_paths,
161 const char* tpa_list)
163 const char *propertyKeys[] =
165 "TRUSTED_PLATFORM_ASSEMBLIES",
168 "NATIVE_DLL_SEARCH_DIRECTORIES",
169 "AppDomainCompatSwitch"
172 const char *propertyValues[] =
175 assembly_probe_paths,
176 assembly_probe_paths,
178 "UseLatestBehaviorWhenTFMNotSpecified"
181 std::string selfPath = ReadSelfPath();
183 int st = InitializeClr(
186 sizeof(propertyKeys) / sizeof(propertyKeys[0]),
194 _ERR("initialize core clr fail! (0x%08x)", st);
198 _DBG("Initialize core clr success");
202 int CoreRuntime::RunManagedLauncher(const char* app_id, const char* app_base, const char* tpa_list)
204 if (FileNotExist(LauncherAssembly))
206 _ERR("Launcher assembly is not exist in %s", LauncherAssembly.c_str());
210 if (!InitializeCoreClr(app_id, app_base, app_base, tpa_list))
212 _ERR("Failed to initialize coreclr");
216 #ifdef USE_MANAGED_LAUNCHER
217 void *preparedFunctionDelegate;
218 int st = CreateDelegate(hostHandle, domainId,
219 "Tizen.Runtime.Coreclr",
220 "Tizen.Runtime.Coreclr.AssemblyManager",
221 "Prepared", &preparedFunctionDelegate);
224 _ERR("Create delegate for Launch prepared function is fail (0x%08x)", st);
227 PreparedFunction = reinterpret_cast<PreparedFunctionPtr>(preparedFunctionDelegate);
229 if(PreparedFunction != nullptr)
234 void *launchFunctionDelegate;
235 st = CreateDelegate(hostHandle, domainId,
236 "Tizen.Runtime.Coreclr",
237 "Tizen.Runtime.Coreclr.AssemblyManager",
238 "Launch", &launchFunctionDelegate);
241 _ERR("Create delegate for Launch managed function is fail! (0x%08x)", st);
244 LaunchFunction = reinterpret_cast<LaunchFunctionPtr>(launchFunctionDelegate);
249 void CoreRuntime::Dispose()
251 if (hostHandle != nullptr)
253 int st = Shutdown(hostHandle, domainId);
256 _ERR("shutdown core clr fail! (0x%08x)", st);
260 if (dlclose(coreclrLib) != 0)
262 _ERR("libcoreclr.so close failed");
264 coreclrLib = nullptr;
266 _DBG("Dotnet runtime disposed");
269 int CoreRuntime::Launch(const char* app_id, const char* root, const char* path, int argc, char* argv[])
273 _ERR("executable path is null");
277 if (FileNotExist(path))
279 _ERR("File not exist : %s", path);
283 std::vector<std::string> searchDirectories = {
284 RuntimeDirectory, DeviceAPIDirectory
285 #ifdef USE_MANAGED_LAUNCHER
286 , Basename(LauncherAssembly)
290 //std::string trusted_directories = JoinStrings(searchDirectories, ":");
292 AssembliesInDirectory(searchDirectories, tpa);
294 std::string appRoot = root;
295 std::string appBin = ConcatPath(appRoot, "bin");
296 std::string appLib = ConcatPath(appRoot, "lib");
297 std::string probePath = appBin + ":" + appLib + ":" + NativeLibDirectory;
299 #ifdef USE_MANAGED_LAUNCHER
300 RunManagedLauncher(app_id, probePath.c_str(), tpa.c_str());
302 bool success = false;
303 if (LaunchFunction != nullptr)
305 std::string cpppath(path);
307 if (IsManagedAssembly(cpppath) && !IsNativeImage(cpppath))
309 size_t extindex = cpppath.size() - 4;
310 cpppath = cpppath.substr(0, extindex) + ".ni" + cpppath.substr(extindex, 4);
311 if (!FileNotExist(cpppath))
313 path = cpppath.c_str();
317 success = LaunchFunction(root, path, argc, argv);
320 _ERR("Failed to launch Application %s", path);
322 return success ? 0 : 1;
326 _ERR("Failed to find launch function");
330 int st = InitializeCoreClr(app_id, probePath.c_str(), probePath.c_str(), tpa.c_str());
331 unsigned int ret = 0;
332 st = ExecuteAssembly(hostHandle, domainId, argc, (const char**)argv, path, &ret);
335 _ERR("Failed to Execute Assembly %s (0x%08x)", path, st);
341 } // namespace dotnetcore
342 } // namespace runtime