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}