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