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}