hostfxr_sys/lib.rs
1#![warn(clippy::pedantic, clippy::cargo, unsafe_op_in_unsafe_fn)]
2#![allow(
3 clippy::missing_safety_doc,
4 clippy::missing_errors_doc,
5 clippy::missing_panics_doc,
6 clippy::module_name_repetitions,
7 clippy::multiple_crate_versions,
8 clippy::doc_markdown,
9 non_camel_case_types,
10 dead_code
11)]
12#![cfg_attr(feature = "doc-cfg", feature(doc_cfg))]
13
14/*!
15FFI bindings for [hostfxr](https://github.com/dotnet/runtime/blob/main/docs/design/features/host-components.md#components-of-the-hosting).
16
17## Related crates
18- [nethost-sys](https://crates.io/crates/nethost-sys) - bindings for the nethost library.
19- [coreclr-hosting-shared](https://crates.io/crates/coreclr-hosting-shared) - shared bindings between this crate and [nethost-sys](https://crates.io/crates/nethost-sys).
20- [netcorehost](https://crates.io/crates/netcorehost) - rusty wrapper over the nethost and hostfxr libraries.
21
22## Additional Information
23- [Hosting layer APIs](https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/hosting-layer-apis.md)
24- [Native hosting](https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/native-hosting.md#runtime-properties)
25- [Write a custom .NET Core host to control the .NET runtime from your native code](https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting)
26
27## License
28Licensed under the MIT license ([LICENSE](https://github.com/OpenByteDev/hostfxr-sys/blob/master/LICENSE) or <http://opensource.org/licenses/MIT>)
29*/
30
31pub use dlopen2;
32
33use core::{ffi::c_void, mem};
34use coreclr_hosting_shared::{char_t, size_t};
35
36/// Signifies that the target method is marked with the [`UnmanagedCallersOnlyAttribute`].
37/// This means that the name alone can identify the target method.
38///
39/// [`UnmanagedCallersOnlyAttribute`]: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute
40#[cfg(feature = "net5_0")]
41#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "net5_0")))]
42pub const UNMANAGED_CALLERS_ONLY_METHOD: *const char_t = usize::MAX as *const _;
43
44/// Seperator char used to seperate a list of paths in a string.
45#[cfg(windows)]
46pub const PATH_LIST_SEPARATOR: char_t = b';' as char_t;
47/// Seperator char used to seperate a list of paths in a string.
48#[cfg(not(windows))]
49#[allow(clippy::cast_possible_wrap)]
50pub const PATH_LIST_SEPARATOR: char_t = b':' as char_t;
51
52#[cfg(feature = "netcore3_0")]
53#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
54#[cfg_attr(feature = "enum-map", derive(enum_map::Enum))]
55#[derive(Clone, Copy, Debug, PartialEq, Eq)]
56#[repr(i32)]
57#[non_exhaustive]
58/// Enum representing the type of runtime functionality requested with `hostfxr_get_runtime_delegate`.
59pub enum hostfxr_delegate_type {
60 hdt_com_activation = 0,
61 /// IJW entry-point
62 hdt_load_in_memory_assembly = 1,
63 /// WinRT activation entry-point
64 #[cfg(all(feature = "netcore3_0", not(feature = "net5_0")))]
65 #[cfg_attr(
66 feature = "doc-cfg",
67 doc(cfg(all(feature = "netcore3_0", not(feature = "net5_0"))))
68 )]
69 hdt_winrt_activation = 2,
70 hdt_com_register = 3,
71 hdt_com_unregister = 4,
72 /// Entry point which loads an assembly (with dependencies) and returns a function pointer for a specified static method.
73 hdt_load_assembly_and_get_function_pointer = 5,
74 /// Entry-point which finds a managed method and returns a function pointer to it.
75 #[cfg(feature = "net5_0")]
76 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "net5_0")))]
77 hdt_get_function_pointer = 6,
78 /// Entry-point which loads an assembly by its path.
79 #[cfg(feature = "net8_0")]
80 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "net8_0")))]
81 hdt_load_assembly = 7,
82 /// Entry-point which loads an assembly from a byte array.
83 #[cfg(feature = "net8_0")]
84 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "net8_0")))]
85 hdt_load_assembly_bytes = 8,
86}
87
88/// Error reporting function signature.
89#[cfg(feature = "netcore3_0")]
90#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
91pub type hostfxr_error_writer_fn = extern "C" fn(message: *const char_t);
92
93/// Flag constants for `hostfxr_resolve_sdk2`.
94#[allow(non_upper_case_globals)]
95#[cfg(feature = "netcore2_1")]
96#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
97#[cfg_attr(feature = "enum-map", derive(enum_map::Enum))]
98#[repr(i32)]
99#[non_exhaustive]
100pub enum hostfxr_resolve_sdk2_flags_t {
101 none = 0x0,
102 disallow_prerelease = 0x1,
103}
104
105/// Possible keys for values passed to the callback in `hostfxr_resolve_sdk2`.
106#[cfg(feature = "netcore2_1")]
107#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
108#[cfg_attr(feature = "enum-map", derive(enum_map::Enum))]
109#[derive(Clone, Copy, Debug, PartialEq, Eq)]
110#[repr(i32)]
111#[non_exhaustive]
112pub enum hostfxr_resolve_sdk2_result_key_t {
113 resolved_sdk_dir = 0,
114 global_json_path = 1,
115 requested_version = 2,
116 global_json_state = 3,
117}
118
119/// Possible values for value in `hostfxr_resolve_sdk2_result_fn` when key is `global_json_state`.
120#[cfg(feature = "netcore2_1")]
121#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
122pub mod hostfxr_resolve_sdk2_global_json_state {
123 // from https://github.com/dotnet/runtime/blob/59a29ee6827ba65477dc8b06132697258ef9c58f/src/native/corehost/fxr/hostfxr.cpp#L185
124 pub const NOT_FOUND: &str = "not_found";
125 pub const VALID: &str = "valid";
126 pub const INVALID_JSON: &str = "invalid_json";
127 pub const INVALID_DATA: &str = "invalid_data";
128}
129
130/// Result callback signature for `hostfxr_resolve_sdk2`.
131#[cfg(feature = "netcore2_1")]
132#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
133pub type hostfxr_resolve_sdk2_result_fn =
134 extern "C" fn(key: hostfxr_resolve_sdk2_result_key_t, value: *const char_t);
135
136/// Result callback signature for `hostfxr_get_available_sdks`.
137#[cfg(feature = "netcore2_1")]
138#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
139pub type hostfxr_get_available_sdks_result_fn =
140 extern "C" fn(sdk_count: i32, sdk_dirs: *const *const char_t);
141
142/// Result callback signature for `hostfxr_get_dotnet_environment_info`.
143#[cfg(all(feature = "net6_0", feature = "undocumented"))]
144#[cfg_attr(
145 feature = "doc-cfg",
146 doc(cfg(all(feature = "net6_0", feature = "undocumented")))
147)]
148pub type hostfxr_get_dotnet_environment_info_result_fn =
149 unsafe extern "C" fn(info: *const hostfxr_dotnet_environment_info, result_context: *mut c_void);
150
151#[cfg(all(feature = "net6_0", feature = "undocumented"))]
152#[cfg_attr(
153 feature = "doc-cfg",
154 doc(cfg(all(feature = "net6_0", feature = "undocumented")))
155)]
156#[derive(Clone, Copy, Debug)]
157#[repr(C)]
158pub struct hostfxr_dotnet_environment_sdk_info {
159 pub size: size_t,
160 pub version: *const char_t,
161 pub path: *const char_t,
162}
163
164#[cfg(all(feature = "net6_0", feature = "undocumented"))]
165#[cfg_attr(
166 feature = "doc-cfg",
167 doc(cfg(all(feature = "net6_0", feature = "undocumented")))
168)]
169#[derive(Clone, Copy, Debug)]
170#[repr(C)]
171pub struct hostfxr_dotnet_environment_framework_info {
172 pub size: size_t,
173 pub name: *const char_t,
174 pub version: *const char_t,
175 pub path: *const char_t,
176}
177
178#[cfg(all(feature = "net6_0", feature = "undocumented"))]
179#[cfg_attr(
180 feature = "doc-cfg",
181 doc(cfg(all(feature = "net6_0", feature = "undocumented")))
182)]
183#[derive(Clone, Copy, Debug)]
184#[repr(C)]
185pub struct hostfxr_dotnet_environment_info {
186 pub size: size_t,
187
188 pub hostfxr_version: *const char_t,
189 pub hostfxr_commit_hash: *const char_t,
190
191 pub sdk_count: size_t,
192 pub sdks: *const hostfxr_dotnet_environment_sdk_info,
193
194 pub framework_count: size_t,
195 pub frameworks: *const hostfxr_dotnet_environment_framework_info,
196}
197
198/// Handle to a hostfxr context.
199pub type hostfxr_handle = *const c_void;
200
201/// Signature of delegate returned by [`hostfxr_get_runtime_delegate`] for type [`hdt_load_assembly_and_get_function_pointer`]
202///
203/// # Arguments
204/// * `assembly_path`:
205/// Fully qualified path to assembly
206/// * `type_name`:
207/// Assembly qualified type name
208/// * `method_name`:
209/// Public static method name compatible with delegateType
210/// * `delegate_type_name`:
211/// Assembly qualified delegate type name or [`null`](core::ptr::null()), or [`UNMANAGED_CALLERS_ONLY_METHOD`] if the method is marked with the [`UnmanagedCallersOnlyAttribute`].
212/// * `load_context`:
213/// Extensibility parameter (currently unused and must be 0)
214/// * `reserved`:
215/// Extensibility parameter (currently unused and must be 0)
216/// * `delegate`:
217/// Pointer where to store the function pointer result
218///
219/// [`hostfxr_get_runtime_delegate`]: wrapper/struct.Hostfxr.html#method.hostfxr_get_runtime_delegate
220/// [`hdt_load_assembly_and_get_function_pointer`]: hostfxr_delegate_type::`hdt_load_assembly_and_get_function_pointer
221/// [`UNMANAGED_CALLERS_ONLY_METHOD`]: UNMANAGED_CALLERS_ONLY_METHOD
222/// [`UnmanagedCallersOnlyAttribute`]: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute
223#[cfg(feature = "netcore3_0")]
224#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
225pub type load_assembly_and_get_function_pointer_fn = unsafe extern "system" fn(
226 assembly_path: *const char_t,
227 type_name: *const char_t,
228 method_name: *const char_t,
229 delegate_type_name: *const char_t,
230 reserved: *const c_void,
231 /*out*/ delegate: *mut *const c_void,
232) -> i32;
233
234/// Signature of delegate returned by [`hostfxr_get_runtime_delegate`] for type [`hdt_get_function_pointer`]
235///
236/// Calling this function will find the specified type in the default load context, locate the required method on it and return a native function pointer to that method.
237/// The method's signature can be specified via the delegate type name.
238///
239/// # Arguments
240/// * `type_name`:
241/// Assembly qualified type name
242/// * `method_name`:
243/// Public static method name compatible with delegateType
244/// * `delegate_type_name`:
245/// Assembly qualified delegate type name or [`null`](core::ptr::null()), or [`UNMANAGED_CALLERS_ONLY_METHOD`] if the method is marked with the [`UnmanagedCallersOnlyAttribute`].
246/// * `load_context`:
247/// Extensibility parameter (currently unused and must be 0)
248/// * `reserved`:
249/// Extensibility parameter (currently unused and must be 0)
250/// * `delegate`:
251/// Pointer where to store the function pointer result
252///
253/// [`hdt_get_function_pointer`]: hostfxr_delegate_type::hdt_get_function_pointer
254/// [`hostfxr_get_runtime_delegate`]: wrapper/struct.Hostfxr.html#method.hostfxr_get_runtime_delegate
255/// [`UNMANAGED_CALLERS_ONLY_METHOD`]: crate::UNMANAGED_CALLERS_ONLY_METHOD
256/// [`UnmanagedCallersOnlyAttribute`]: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute
257#[cfg(feature = "net5_0")]
258#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "net5_0")))]
259pub type get_function_pointer_fn = unsafe extern "system" fn(
260 type_name: *const char_t,
261 method_name: *const char_t,
262 delegate_type_name: *const char_t,
263 load_context: *const c_void,
264 reserved: *const c_void,
265 /*out*/ delegate: *mut *const c_void,
266) -> i32;
267
268/// Signature of delegate returned by [`load_assembly_and_get_function_pointer_fn`] when `delegate_type_name == null` (default)
269#[cfg(feature = "netcore3_0")]
270#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
271pub type component_entry_point_fn = unsafe extern "system" fn(*const c_void, i32) -> i32;
272
273/// Signature of delegate returned by [`hostfxr_get_runtime_delegate`] for type [`hdt_load_assembly`].
274///
275/// Calling this function will load the specified assembly in the default load context.
276/// It uses [`AssemblyDependencyResolver`] to register additional dependency resolution for the load context.
277///
278/// # Arguments
279/// * `assembly_path`:
280/// Path to the assembly to load - requirements match the assemblyPath parameter of [`AssemblyLoadContext.LoadFromAssemblyPath`].
281/// This path will also be used for dependency resolution via any `.deps.json` corresponding to the assembly.
282/// * `load_context`:
283/// The load context that will be used to load the assembly.
284/// For .NET 8 this parameter must be [`null`](core::ptr::null()) and the API will only load the assembly in the default load context.
285/// * `reserved`:
286/// Parameter reserved for future extensibility, currently unused and must be [`null`](core::ptr::null()).
287///
288/// [`hdt_load_assembly`]: hostfxr_delegate_type::hdt_load_assembly
289/// [`hostfxr_get_runtime_delegate`]: wrapper/struct.Hostfxr.html#method.hostfxr_get_runtime_delegate
290/// [`AssemblyDependencyResolver`]: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblydependencyresolver
291/// [`AssemblyLoadContext.LoadFromAssemblyPath`]: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext.loadfromassemblypath
292#[cfg(feature = "net8_0")]
293#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "net8_0")))]
294pub type load_assembly_fn = unsafe extern "system" fn(
295 assembly_path: *const char_t,
296 load_context: *const c_void,
297 reserved: *const c_void,
298) -> i32;
299
300/// Signature of delegate returned by [`hostfxr_get_runtime_delegate`] for type [`hdt_load_assembly_bytes`]
301///
302/// Calling this function will load the specified assembly in the default load context.
303/// It does not provide a mechanism for registering additional dependency resolution, as mechanisms like `.deps.json` and [`AssemblyDependencyResolver`] are file-based.
304/// Dependencies can be pre-loaded (for example, via a previous call to this function) or the specified assembly can explicitly register its own resolution logic (for example, via the [`AssemblyLoadContext.Resolving`] event).
305/// It uses [`AssemblyDependencyResolver`] to register additional dependency resolution for the load context.
306///
307/// # Arguments
308/// * `assembly_path`:
309/// Path to the assembly to load - requirements match the assemblyPath parameter of [`AssemblyLoadContext.LoadFromAssemblyPath`].
310/// This path will also be used for dependency resolution via any `.deps.json` corresponding to the assembly.
311/// * `load_context`:
312/// The load context that will be used to load the assembly.
313/// For .NET 8 this parameter must be [`null`](core::ptr::null()) and the API will only load the assembly in the default load context.
314/// * `reserved`:
315/// Parameter reserved for future extensibility, currently unused and must be [`null`](core::ptr::null()).
316///
317/// [`hdt_load_assembly_bytes`]: hostfxr_delegate_type::hdt_load_assembly_bytes
318/// [`hostfxr_get_runtime_delegate`]: wrapper/struct.Hostfxr.html#method.hostfxr_get_runtime_delegate
319/// [`AssemblyDependencyResolver`]: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblydependencyresolver
320/// [`AssemblyLoadContext.Resolving`]: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext.resolving?view=net-7.0
321/// [`AssemblyLoadContext.LoadFromAssemblyPath`]: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext.loadfromassemblypath
322#[cfg(feature = "net8_0")]
323#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "net8_0")))]
324pub type load_assembly_bytes_fn = unsafe extern "system" fn(
325 assembly_bytes: *const u8,
326 assembly_bytes_len: usize,
327 symbols_bytes: *const u8,
328 symbols_bytes_len: usize,
329 load_context: *const c_void,
330 reserved: *const c_void,
331) -> i32;
332
333/// A structure that stores parameters which are common to all forms of initialization.
334#[derive(Clone, Copy, Debug)]
335#[repr(C)]
336pub struct hostfxr_initialize_parameters {
337 /// The size of the structure.
338 /// This is used for versioning.
339 /// Should be set to `mem::size_of::<hostfxr_initialize_parameters>()`.
340 pub size: size_t,
341 /// Path to the native host (typically the `.exe`).
342 /// This value is not used for anything by the hosting components.
343 /// It's just passed to the CoreCLR as the path to the executable.
344 /// It can point to a file which is not executable itself, if such file doesn't exist
345 /// (for example in COM activation scenarios this points to the `comhost.dll`).
346 /// This is used by PAL (Platform Abstraction Layer) to initialize internal command line structures, process name and so on.
347 pub host_path: *const char_t,
348 /// Path to the root of the .NET Core installation in use.
349 /// This typically points to the install location from which the hostfxr has been loaded.
350 /// For example on Windows this would typically point to `C:\Program Files\dotnet`.
351 /// The path is used to search for shared frameworks and potentially SDKs.
352 pub dotnet_root: *const char_t,
353}
354
355impl hostfxr_initialize_parameters {
356 /// Creates a new instance with the given `host_path`.
357 /// The `size` field is set accordingly to the size of the struct and `dotnet_root` to [`core::ptr::null()`].
358 #[must_use]
359 pub fn with_host_path(host_path: *const char_t) -> Self {
360 Self {
361 size: mem::size_of::<Self>(),
362 host_path,
363 dotnet_root: core::ptr::null(),
364 }
365 }
366 /// Creates a new instance with the given `dotnet_root`.
367 /// The `size` field is set accordingly to the size of the struct and `host_path` to [`core::ptr::null()`].
368 #[must_use]
369 pub fn with_dotnet_root(dotnet_root: *const char_t) -> Self {
370 Self {
371 size: mem::size_of::<Self>(),
372 host_path: core::ptr::null(),
373 dotnet_root,
374 }
375 }
376}
377
378macro_rules! derive_apis {
379 (
380 $( #[$struct_attrs:meta] )*
381 $visibility:vis struct $name:ident {
382 $(
383 $( #[$field_attrs:meta] )*
384 $field:ident : $field_type:ty,
385 )*
386 }) => {
387 /// [`dlopen2::symbor`] abstraction for the hostfxr library.
388 #[cfg(feature = "symbor")]
389 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "symbor")))]
390 $visibility mod symbor {
391 #[allow(unused_imports)]
392 use super::*;
393 use dlopen2::symbor::{Symbol, SymBorApi};
394
395 /// [`dlopen2::symbor`] abstraction for the hostfxr library.
396 $( #[$struct_attrs] )*
397 #[derive(SymBorApi)]
398 $visibility struct $name <'lib> {
399 // ensures that 'lib is used
400 #[cfg(not(feature = "netcore1_0"))]
401 _dummy: Option<Symbol<'lib, fn()>>,
402
403 $(
404 $( #[$field_attrs] )*
405 pub $field : Symbol<'lib, $field_type>
406 ),*
407 }
408 }
409
410 /// [`dlopen2::symbor`] abstraction for the hostfxr library, with all symbols marked as optional.
411 #[cfg(all(feature = "symbor", feature = "optional-apis"))]
412 #[cfg_attr(feature = "doc-cfg", doc(cfg(all(feature = "symbor", feature = "optional-apis"))))]
413 $visibility mod symbor_option {
414 #[allow(unused_imports)]
415 use super::*;
416 use dlopen2::symbor::{Symbol, SymBorApi};
417
418 /// [`dlopen2::symbor`] abstraction for the hostfxr library, with all symbols marked as optional.
419 $( #[$struct_attrs] )*
420 #[derive(SymBorApi)]
421 $visibility struct $name <'lib> {
422 // ensures that 'lib is used
423 #[cfg(not(feature = "netcore1_0"))]
424 _dummy: Option<Symbol<'lib, fn()>>,
425
426 $(
427 $( #[$field_attrs] )*
428 pub $field : Option<Symbol<'lib, $field_type>>
429 ),*
430 }
431 }
432
433 /// [`dlopen2::wrapper`] abstraction for the hostfxr library.
434 #[cfg(feature = "wrapper")]
435 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "wrapper")))]
436 $visibility mod wrapper {
437 #[allow(unused_imports)]
438 use super::*;
439 use dlopen2::wrapper::WrapperApi;
440
441 /// [`dlopen2::wrapper`] abstraction for the hostfxr library.
442 $( #[$struct_attrs] )*
443 #[derive(WrapperApi)]
444 $visibility struct $name {
445 $(
446 $( #[$field_attrs] )*
447 $field : $field_type
448 ),*
449 }
450 }
451
452 /// [`dlopen2::wrapper`] abstraction for the hostfxr library, with all symbols marked as optional.
453 #[cfg(all(feature = "wrapper", feature = "optional-apis"))]
454 #[cfg_attr(feature = "doc-cfg", doc(cfg(all(feature = "wrapper", feature = "optional-apis"))))]
455 $visibility mod wrapper_option {
456 #[allow(unused_imports)]
457 use super::*;
458 use dlopen2::wrapper::WrapperApi;
459
460 /// [`dlopen2::wrapper`] abstraction for the hostfxr library, with all symbols marked as optional.
461 $( #[$struct_attrs] )*
462 #[derive(WrapperApi)]
463 $visibility struct $name {
464 $(
465 $( #[$field_attrs] )*
466 $field : Option<$field_type>
467 ),*
468 }
469 }
470 }
471}
472
473derive_apis! {
474 #[allow(clippy::struct_field_names)]
475 pub struct Hostfxr {
476 /// Run an application.
477 ///
478 /// # Arguments
479 /// * `argv` - command-line arguments
480 ///
481 /// This function does not return until the application completes execution.
482 /// It will shutdown CoreCLR after the application executes.
483 /// If the application is successfully executed, this value will return the exit code of the application. Otherwise, it will return an error code indicating the failure.
484 #[cfg(feature = "netcore1_0")]
485 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore1_0")))]
486 hostfxr_main: unsafe extern "C" fn(argc: i32, argv: *const *const char_t) -> i32,
487
488 /// Determines the directory location of the SDK accounting for
489 /// `global.json` and multi-level lookup policy.
490 ///
491 /// Invoked via MSBuild SDK resolver to locate SDK props and targets
492 /// from an msbuild other than the one bundled by the CLI.
493 ///
494 /// # Arguments
495 /// * `exe_dir`
496 /// The main directory where SDKs are located in `sdk\[version]`
497 /// sub-folders. Pass the directory of a dotnet executable to
498 /// mimic how that executable would search in its own directory.
499 /// It is also valid to pass nullptr or empty, in which case
500 /// multi-level lookup can still search other locations if
501 /// it has not been disabled by the user's environment.
502 /// * `working_dir`
503 /// The directory where the search for `global.json` (which can
504 /// control the resolved SDK version) starts and proceeds
505 /// upwards.
506 /// * `buffer`
507 /// The buffer where the resolved SDK path will be written.
508 /// * `buffer_size`
509 /// The size of the buffer argument in [`char_t`] units.
510 ///
511 /// # Return value:
512 /// * `<0` - Invalid argument
513 /// * `0` - SDK could not be found.
514 /// * `>0` - The number of characters (including null terminator)
515 /// required to store the located SDK.
516 ///
517 /// If resolution succeeds and the positive return value is less than
518 /// or equal to `buffer_size` (i.e. the the buffer is large enough),
519 /// then the resolved SDK path is copied to the buffer and null
520 /// terminated. Otherwise, no data is written to the buffer.
521 #[deprecated(note = "Use `hostfxr_resolve_sdk2` instead.")]
522 #[cfg(feature = "netcore2_0")]
523 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_0")))]
524 hostfxr_resolve_sdk: unsafe extern "C" fn(
525 exe_dir: *const char_t,
526 working_dir: *const char_t,
527 buffer: *mut char_t,
528 buffer_size: i32,
529 ) -> i32,
530
531 /// Run an application.
532 ///
533 /// # Arguments
534 /// * `argv`
535 /// command-line arguments
536 /// * `host_path`
537 /// path to the host application
538 /// * `dotnet_root`
539 /// path to the .NET Core installation root
540 /// * `app_path`
541 /// path to the application to run
542 ///
543 /// This function does not return until the application completes execution.
544 /// It will shutdown CoreCLR after the application executes.
545 /// If the application is successfully executed, this value will return the exit code of the application. Otherwise, it will return an error code indicating the failure.
546 #[cfg(feature = "netcore2_1")]
547 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
548 hostfxr_main_startupinfo: unsafe extern "C" fn(
549 argc: i32,
550 argv: *const *const char_t,
551 host_path: *const char_t,
552 dotnet_root: *const char_t,
553 app_path: *const char_t,
554 ) -> i32,
555
556 #[cfg(all(feature = "netcore2_1", feature = "undocumented"))]
557 #[cfg_attr(
558 feature = "doc-cfg",
559 doc(cfg(all(feature = "netcore2_1", feature = "undocumented")))
560 )]
561 hostfxr_main_bundle_startupinfo: unsafe extern "C" fn(
562 argc: i32,
563 argv: *const *const char_t,
564 host_path: *const char_t,
565 dotnet_root: *const char_t,
566 app_path: *const char_t,
567 bundle_header_offset: i64,
568 ) -> i32,
569
570 /// Determine the directory location of the SDK, accounting for `global.json` and multi-level lookup policy.
571 ///
572 /// # Arguments
573 /// * `exe_dir` main directory where SDKs are located in `sdk\[version]` sub-folders.
574 /// * `working_dir` directory where the search for `global.json` will start and proceed upwards
575 /// * `flags` flags that influence resolution:
576 /// `disallow_prerelease` - do not allow resolution to return a pre-release SDK version unless a pre-release version was specified via `global.json`
577 /// * `result` callback invoked to return resolved values.
578 /// The callback may be invoked more than once. Strings passed to the callback are valid only for the duration of the call.
579 ///
580 /// If resolution succeeds, result will be invoked with [`resolved_sdk_dir`](crate::hostfxr_resolve_sdk2_result_key_t::resolved_sdk_dir) key and the value will hold the path to the resolved SDK directory.
581 /// If resolution does not succeed, result will be invoked with [`resolved_sdk_dir`](crate::hostfxr_resolve_sdk2_result_key_t::resolved_sdk_dir) key and the value will be [`ptr::null()`](core::ptr::null).
582 ///
583 /// If `global.json` is used, result will be invoked with [`global_json_path`](crate::hostfxr_resolve_sdk2_result_key_t::global_json_path) key and the value will hold the path to `global.json`.
584 /// If there was no `global.json` found, or the contents of `global.json` did not impact resolution (e.g. no version specified), then result will not be invoked with [`global_json_path`](crate::hostfxr_resolve_sdk2_result_key_t::global_json_path) key.
585 #[cfg(feature = "netcore2_1")]
586 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
587 hostfxr_resolve_sdk2: unsafe extern "C" fn(
588 exe_dir: *const char_t,
589 working_dir: *const char_t,
590 flags: hostfxr_resolve_sdk2_flags_t,
591 result: hostfxr_resolve_sdk2_result_fn,
592 ) -> i32,
593
594 /// Get the list of all available SDKs ordered by ascending version.
595 ///
596 /// # Arguments
597 /// * `exe_dir` - path to the dotnet executable
598 /// * `result` - callback invoked to return the list of SDKs by their directory paths.
599 /// String array and its elements are valid only for the duration of the call.
600 #[cfg(feature = "netcore2_1")]
601 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
602 hostfxr_get_available_sdks: unsafe extern "C" fn(
603 exe_dir: *const char_t,
604 result: hostfxr_get_available_sdks_result_fn,
605 ) -> i32,
606
607 /// Get the native search directories of the runtime based upon the specified app.
608 ///
609 /// # Arguments
610 /// * `argc`,`argv` command-line arguments
611 /// * `buffer` buffer to populate with the native search directories (including a null terminator).
612 /// * `buffer_size` size of `buffer` in [`char_t`] units
613 /// * `required_buffer_size` if buffer is too small, this will be populated with the minimum required buffer size (including a null terminator). Otherwise, this will be set to 0.
614 ///
615 /// The native search directories will be a list of paths separated by [`PATH_LIST_SEPARATOR`], which is a semicolon (;) on Windows and a colon (:) otherwise.
616 ///
617 /// If `buffer_size` is less than the minimum required buffer size, this function will return [`HostApiBufferTooSmall`] and buffer will be unchanged.
618 ///
619 /// [`HostApiBufferTooSmall`]: coreclr_hosting_shared::StatusCode::HostApiBufferTooSmall
620 /// [`PATH_LIST_SEPARATOR`]: crate::PATH_LIST_SEPARATOR
621 #[cfg(feature = "netcore2_1")]
622 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore2_1")))]
623 hostfxr_get_native_search_directories: unsafe extern "C" fn(
624 argc: i32,
625 argv: *const *const char_t,
626 buffer: *mut char_t,
627 buffer_size: i32,
628 required_buffer_size: *mut i32,
629 ) -> i32,
630
631 /// Sets a callback which is to be used to write errors to.
632 ///
633 /// # Arguments
634 /// * `error_writer`
635 /// A callback function which will be invoked every time an error is to be reported.
636 /// Or [`null`](core::ptr::null()) to unregister previously registered callback and return to the default behavior.
637 ///
638 /// # Return value
639 /// The previously registered callback (which is now unregistered), or [`null`](core::ptr::null()) if no previous callback
640 /// was registered
641 ///
642 /// # Remarks
643 /// The error writer is registered per-thread, so the registration is thread-local. On each thread
644 /// only one callback can be registered. Subsequent registrations overwrite the previous ones.
645 ///
646 /// By default no callback is registered in which case the errors are written to stderr.
647 ///
648 /// Each call to the error writer is sort of like writing a single line (the EOL character is omitted).
649 /// Multiple calls to the error writer may occure for one failure.
650 ///
651 /// If the hostfxr invokes functions in hostpolicy as part of its operation, the error writer
652 /// will be propagated to hostpolicy for the duration of the call. This means that errors from
653 /// both hostfxr and hostpolicy will be reporter through the same error writer.
654 #[cfg(feature = "netcore3_0")]
655 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
656 hostfxr_set_error_writer:
657 unsafe extern "C" fn(error_writer: Option<hostfxr_error_writer_fn>) -> Option<hostfxr_error_writer_fn>,
658
659 /// Initializes the hosting components for a dotnet command line running an application
660 ///
661 /// # Arguments
662 /// * `argc`
663 /// Number of argv arguments
664 /// * `argv`
665 /// Command-line arguments for running an application (as if through the dotnet executable).
666 /// * `parameters`
667 /// Optional. Additional parameters for initialization
668 /// * `host_context_handle`
669 /// On success, this will be populated with an opaque value representing the initialized host context
670 ///
671 /// # Return value
672 /// * [`Success`]:
673 /// Hosting components were successfully initialized
674 /// * [`HostInvalidState`]:
675 /// Hosting components are already initialized
676 ///
677 /// # Remarks
678 /// This function parses the specified command-line arguments to determine the application to run. It will
679 /// then find the corresponding `.runtimeconfig.json` and `.deps.json` with which to resolve frameworks and
680 /// dependencies and prepare everything needed to load the runtime.
681 ///
682 /// This function only supports arguments for running an application. It does not support SDK commands.
683 ///
684 /// This function does not load the runtime.
685 ///
686 /// [`Success`]: coreclr_hosting_shared::StatusCode::Success
687 /// [`HostInvalidState`]: coreclr_hosting_shared::StatusCode::HostInvalidState
688 #[cfg(feature = "netcore3_0")]
689 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
690 hostfxr_initialize_for_dotnet_command_line: unsafe extern "C" fn(
691 argc: i32,
692 argv: *const *const char_t,
693 parameters: *const hostfxr_initialize_parameters,
694 /*out*/ host_context_handle: *mut hostfxr_handle,
695 ) -> i32,
696
697 /// Initializes the hosting components using a `.runtimeconfig.json` file
698 ///
699 /// # Arguments
700 /// * `runtime_config_path`
701 /// Path to the `.runtimeconfig.json` file
702 /// * `parameters`
703 /// Optional. Additional parameters for initialization
704 /// * `host_context_handle`
705 /// On success, this will be populated with an opaque value representing the initialized host context
706 ///
707 /// # Return value
708 /// * [`Success`]:
709 /// Hosting components were successfully initialized
710 /// * [`Success_HostAlreadyInitialized`]:
711 /// Config is compatible with already initialized hosting components
712 /// * [`Success_DifferentRuntimeProperties`]:
713 /// Config has runtime properties that differ from already initialized hosting components
714 /// * [`CoreHostIncompatibleConfig`]:
715 /// Config is incompatible with already initialized hosting components
716 ///
717 /// # Remarks
718 /// This function will process the `.runtimeconfig.json` to resolve frameworks and prepare everything needed
719 /// to load the runtime. It will only process the `.deps.json` from frameworks (not any app/component that
720 /// may be next to the `.runtimeconfig.json`).
721 ///
722 /// This function does not load the runtime.
723 ///
724 /// If called when the runtime has already been loaded, this function will check if the specified runtime
725 /// config is compatible with the existing runtime.
726 ///
727 /// Both [`Success_HostAlreadyInitialized`] and [`Success_DifferentRuntimeProperties`] codes are considered successful
728 /// initializations. In the case of [`Success_DifferentRuntimeProperties`], it is left to the consumer to verify that
729 /// the difference in properties is acceptable.
730 ///
731 /// [`Success`]: coreclr_hosting_shared::StatusCode::Success
732 /// [`Success_HostAlreadyInitialized`]: coreclr_hosting_shared::StatusCode::Success_HostAlreadyInitialized
733 /// [`Success_DifferentRuntimeProperties`]: coreclr_hosting_shared::StatusCode::Success_DifferentRuntimeProperties
734 /// [`CoreHostIncompatibleConfig`]: coreclr_hosting_shared::StatusCode::CoreHostIncompatibleConfig
735 #[cfg(feature = "netcore3_0")]
736 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
737 hostfxr_initialize_for_runtime_config: unsafe extern "C" fn(
738 runtime_config_path: *const char_t,
739 parameters: *const hostfxr_initialize_parameters,
740 /*out*/ host_context_handle: *mut hostfxr_handle,
741 ) -> i32,
742
743 /// Gets the runtime property value for an initialized host context
744 ///
745 /// # Arguments
746 /// * `host_context_handle`
747 /// Handle to the initialized host context
748 /// * `name`
749 /// Runtime property name
750 /// * `value`
751 /// Out parameter. Pointer to a buffer with the property value.
752 ///
753 /// # Return value
754 /// The error code result.
755 ///
756 /// # Remarks
757 /// The buffer pointed to by value is owned by the host context. The lifetime of the buffer is only
758 /// guaranteed until any of the below occur:
759 /// * a 'run' method is called for the host context
760 /// * properties are changed via [`hostfxr_set_runtime_property_value`]
761 /// * the host context is closed via [`hostfxr_close`]
762 ///
763 /// If `host_context_handle` is [`null`](core::ptr::null()) and an active host context exists, this function will get the
764 /// property value for the active host context.
765 ///
766 /// [`hostfxr_set_runtime_property_value`]: struct.HostfxrLib.html#method.hostfxr_set_runtime_property_value
767 /// [`hostfxr_close`]: struct.HostfxrLib.html#method.hostfxr_close
768 #[cfg(feature = "netcore3_0")]
769 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
770 hostfxr_get_runtime_property_value: unsafe extern "C" fn(
771 host_context_handle: hostfxr_handle,
772 name: *const char_t,
773 /*out*/ value: *mut *const char_t,
774 ) -> i32,
775
776 /// Sets the value of a runtime property for an initialized host context
777 ///
778 /// # Arguments
779 /// * `host_context_handle`
780 /// Handle to the initialized host context
781 /// * `name`
782 /// Runtime property name
783 /// * `value`
784 /// Value to set
785 ///
786 /// # Return value
787 /// The error code result.
788 ///
789 /// # Remarks
790 /// Setting properties is only supported for the first host context, before the runtime has been loaded.
791 ///
792 /// If the property already exists in the host context, it will be overwritten. If value is [`null`](core::ptr::null()), the
793 /// property will be removed.
794 #[cfg(feature = "netcore3_0")]
795 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
796 hostfxr_set_runtime_property_value: unsafe extern "C" fn(
797 host_context_handle: hostfxr_handle,
798 name: *const char_t,
799 value: *const char_t,
800 ) -> i32,
801
802 /// Gets all the runtime properties for an initialized host context
803 ///
804 /// # Arguments
805 /// * `host_context_handle`
806 /// Handle to the initialized host context
807 /// * `count`
808 /// \[in\] Size of the keys and values buffers
809 /// \[out\] Number of properties returned (size of keys/values buffers used). If the input value is too
810 /// small or keys/values is [`null`](core::ptr::null()), this is populated with the number of available properties
811 /// * `keys`
812 /// \[out\] Array of pointers to buffers with runtime property keys
813 /// * `values`
814 /// \[out\] Array of pointers to buffers with runtime property values
815 ///
816 /// # Return value
817 /// The error code result.
818 ///
819 /// # Remarks
820 /// The buffers pointed to by keys and values are owned by the host context. The lifetime of the buffers is only
821 /// guaranteed until any of the below occur:
822 /// * a 'run' method is called for the host context
823 /// * properties are changed via [`hostfxr_set_runtime_property_value`]
824 /// * the host context is closed via [`hostfxr_close`]
825 ///
826 /// If host_context_handle is [`null`](core::ptr::null()) and an active host context exists, this function will get the
827 /// properties for the active host context.
828 ///
829 /// [`hostfxr_set_runtime_property_value`]: struct.HostfxrLib.html#hostfxr_set_runtime_property_value
830 /// [`hostfxr_close`]: struct.HostfxrLib.html#method.hostfxr_closee
831 #[cfg(feature = "netcore3_0")]
832 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
833 hostfxr_get_runtime_properties: unsafe extern "C" fn(
834 host_context_handle: hostfxr_handle,
835 /*inout*/ count: *mut size_t,
836 /*out*/ keys: *mut *const char_t,
837 /*out*/ values: *mut *const char_t,
838 ) -> i32,
839
840 /// Load CoreCLR and run the application for an initialized host context
841 ///
842 /// # Arguments
843 /// * `host_context_handle`
844 /// Handle to the initialized host context
845 ///
846 /// # Return value
847 /// If the app was successfully run, the exit code of the application. Otherwise, the error code result.
848 ///
849 /// # Remarks
850 /// The `host_context_handle` must have been initialized using [`hostfxr_initialize_for_dotnet_command_line`].
851 ///
852 /// This function will not return until the managed application exits.
853 ///
854 /// [`hostfxr_initialize_for_runtime_config`]: struct.HostfxrLib.html#method.hostfxr_initialize_for_runtime_config
855 /// [`hostfxr_initialize_for_dotnet_command_line`]: struct.HostfxrLib.html#method.hostfxr_initialize_for_dotnet_command_line
856 #[cfg(feature = "netcore3_0")]
857 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
858 hostfxr_run_app: unsafe extern "C" fn(host_context_handle: hostfxr_handle) -> i32,
859
860 /// Gets a typed delegate from the currently loaded CoreCLR or from a newly created one.
861 ///
862 /// # Arguments
863 /// * `host_context_handle`
864 /// Handle to the initialized host context
865 /// * `type`
866 /// Type of runtime delegate requested
867 /// * `delegate`
868 /// An out parameter that will be assigned the delegate.
869 ///
870 /// # Return value
871 /// The error code result.
872 ///
873 /// # Remarks
874 /// If the `host_context_handle` was initialized using [`hostfxr_initialize_for_runtime_config`],
875 /// then all delegate types are supported.
876 /// If the host_context_handle was initialized using [`hostfxr_initialize_for_dotnet_command_line`],
877 /// then only the following delegate types are currently supported:
878 /// * [`hdt_load_assembly_and_get_function_pointer`]
879 /// * [`hdt_get_function_pointer`]
880 ///
881 /// [`hdt_load_assembly_and_get_function_pointer`]: hostfxr_delegate_type::hdt_load_assembly_and_get_function_pointer
882 /// [`hdt_get_function_pointer`]: hostfxr_delegate_type::hdt_get_function_pointer
883 /// [`hostfxr_initialize_for_runtime_config`]: struct.HostfxrLib.html#method.hostfxr_initialize_for_runtime_config
884 /// [`hostfxr_initialize_for_dotnet_command_line`]: struct.HostfxrLib.html#method.hostfxr_initialize_for_dotnet_command_line
885 #[cfg(feature = "netcore3_0")]
886 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
887 hostfxr_get_runtime_delegate: unsafe extern "C" fn(
888 host_context_handle: hostfxr_handle,
889 r#type: hostfxr_delegate_type,
890 /*out*/ delegate: *mut *const (),
891 ) -> i32,
892
893 /// Closes an initialized host context.
894 ///
895 /// # Arguments
896 /// * `host_context_handle`
897 /// Handle to the initialized host context
898 ///
899 /// # Return value
900 /// The error code result.
901 #[cfg(feature = "netcore3_0")]
902 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "netcore3_0")))]
903 hostfxr_close: unsafe extern "C" fn(host_context_handle: hostfxr_handle) -> i32,
904
905 /// Returns available SDKs and frameworks.
906 ///
907 /// Resolves the existing SDKs and frameworks from a dotnet root directory (if
908 /// any), or the global default location. If multi-level lookup is enabled and
909 /// the dotnet root location is different than the global location, the SDKs and
910 /// frameworks will be enumerated from both locations.
911 ///
912 /// The SDKs are sorted in ascending order by version, multi-level lookup
913 /// locations are put before private ones.
914 ///
915 /// The frameworks are sorted in ascending order by name followed by version,
916 /// multi-level lookup locations are put before private ones.
917 ///
918 /// # Arguments
919 /// * `dotnet_root`
920 /// The path to a directory containing a dotnet executable.
921 /// * `reserved`
922 /// Reserved for future parameters.
923 /// * `result`
924 /// Callback invoke to return the list of SDKs and frameworks.
925 /// Structs and their elements are valid for the duration of the call.
926 /// * `result_context`
927 /// Additional context passed to the result callback.
928 ///
929 /// # Return value
930 /// The error code result.
931 #[cfg(all(feature = "net6_0", feature = "undocumented"))]
932 #[cfg_attr(feature = "doc-cfg", doc(cfg(all(feature = "net6_0", feature = "undocumented"))))]
933 hostfxr_get_dotnet_environment_info: unsafe extern "C" fn(
934 dotnet_root: *const char_t,
935 reserved: *mut c_void,
936 result: hostfxr_get_dotnet_environment_info_result_fn,
937 result_context: *mut c_void
938 ) -> i32,
939 }
940}