news 2026/9/18 4:48:48

.NET 运行时 hostfxr 与 hostpolicy:托管层 C 风格 API 全景解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
.NET 运行时 hostfxr 与 hostpolicy:托管层 C 风格 API 全景解析

.NET 运行时 hostfxr 与 hostpolicy:托管层 C 风格 API 全景解析

【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime

本文基于 .NET runtime 仓库的设计文档 hosting-layer-apis.md 系统梳理 .NET 托管层(Hosting Layer)对外暴露的全部 C 风格 API:hostfxr(宿主框架解析器)负责定位安装、解析 SDK/框架配置并管理宿主上下文生命周期,hostpolicy(宿主策略)负责依赖解析并实际加载 CoreCLR。读完后,你将能够在自研宿主程序中通过hostfxr_initialize_for_runtime_confighostfxr_get_runtime_delegatecorehost_initialize等 API 完成“宿主中加载运行时、执行应用或获取函数指针”的完整集成,并理解各参数的取值、错误码约定与线程模型。

一、托管层的整体定位

在 .NET 的安装布局中,用户代码不会直接调用 CoreCLR,而是经由两层原生库接入:

  • hostfxrlibhostfxr.so/hostfxr.dll):第一层入口。它负责解析 .NET 安装根目录、global.json、SDK 与框架版本,读取.runtimeconfig.json.deps.json,准备“加载运行时所需的一切”,但本身不加载 CoreCLR。其源码位于 fxr 目录(hostfxr.cpp 是所有导出函数的实现位置),公开声明见 hostfxr.h。
  • hostpolicylibhostpolicy.so/hostpolicy.dll):第二层。它承接 hostfxr 传入的配置,解析组件依赖并真正加载、初始化 CoreCLR(coreclr_initialize/coreclr_execute_assembly)。源码位于 hostpolicy 目录(hostpolicy.cpp),公开声明见 hostpolicy.h。

两层之间通过host_interface_t结构体传递初始化上下文,其布局在 host_interface.h 中定义,并附带了大量static_assert保证字段偏移的向后兼容(该文件注释明确要求“只能追加字段、不得重排或修改字段类型”),这是跨版本兼容性的核心手段。

文档中引用的进阶主题另有专文:原生托管场景见 native-hosting.md,宿主中的组件依赖解析见 host-component-dependencies-resolution.md,错误码总表见 host-error-codes.md。

字符串编码约定:char_t

所有 API 中的char_t字符串按平台定义:

平台编码类型
WindowsUTF-162 字节wchar_t(Visual Studio 默认的 native type 定义)
UnixUTF-81 字节char

这一约定在源码中与文档一致:hostfxr.h 在 Windows 下将char_t定义为wchar_t(未定义时退化为unsigned short),否则定义为char

调用约定

hostfxr 与 hostpolicy 两个库的所有导出函数及函数指针,在 x86 平台上均使用__cdecl调用约定。源码中通过HOSTFXR_CALLTYPE/HOSTPOLICY_CALLTYPE宏实现平台适配:仅在_WIN32下定义为__cdecl,其他平台为空(见 hostfxr.h 与 hostpolicy.h)。

二、Host FXR API

.NET Core 1.0+:hostfxr_main

int hostfxr_main(const int argc, const char_t *argv[])

运行一个应用程序。

  • argc/argv— 命令行参数。

该函数在应用执行完毕前不返回,并在应用执行结束后关闭 CoreCLR。应用成功执行时返回应用的退出码;否则返回表示失败的错误码。实现位于 hostfxr.cpp。

此外,从源码导出表可以看到为单文件 Bundle 场景还提供了hostfxr_main_bundle_startupinfo(在hostfxr_main_startupinfo基础上多一个bundle_header_offset参数),声明见 hostfxr.h,实现见 hostfxr.cpp。

.NET Core 2.0+:hostfxr_resolve_sdk(已废弃)

int32_t hostfxr_resolve_sdk( const char_t *exe_dir, const char_t *working_dir, char_t buffer[], int32_t buffer_size)

已废弃(Obsolete),应改用hostfxr_resolve_sdk2。源码中同样标注了[OBSOLETE] Replaced by hostfxr_resolve_sdk2(hostfxr.cpp)。

.NET Core 2.1+:hostfxr_main_startupinfo

int hostfxr_main_startupinfo( const int argc, const char_t *argv[], const char_t *host_path, const char_t *dotnet_root, const char_t *app_path)

运行一个应用程序。相比hostfxr_main显式传入启动信息:

  • argc/argv— 命令行参数;
  • host_path— 宿主应用程序路径;
  • dotnet_root— .NET Core 安装根目录路径;
  • app_path— 要运行的应用路径。

行为与hostfxr_main相同:应用执行完毕前不返回,执行后关闭 CoreCLR;成功时返回应用退出码,否则返回错误码。

.NET Core 2.1+:hostfxr_resolve_sdk2

enum hostfxr_resolve_sdk2_flags_t { disallow_prerelease = 0x1, }; enum hostfxr_resolve_sdk2_result_key_t { resolved_sdk_dir = 0, global_json_path = 1, }; typedef void (*hostfxr_resolve_sdk2_result_fn)( hostfxr_resolve_sdk2_result_key_t key, const char_t* value); int32_t hostfxr_resolve_sdk2( const char_t *exe_dir, const char_t *working_dir, int32_t flags, hostfxr_resolve_sdk2_result_fn result)

考虑global.json的影响,确定 SDK 目录位置。

  • exe_dir— 主目录,SDK 位于其下sdk\[version]子目录中;
  • working_dir— 从该目录开始向上查找global.json的起点;
  • flags— 影响解析的标志位:
    • disallow_prerelease— 除非global.json明确指定了预发布版本,否则解析结果不允许返回预发布 SDK;
  • result— 回调函数,用于返回解析值。回调可能被调用多次;传入回调的字符串仅在调用期间有效。

回调语义:

  1. 若解析成功,result会以resolved_sdk_dir为 key 被调用,值为解析出的 SDK 目录路径;若解析失败,result仍以resolved_sdk_dir为 key 被调用,但值为nullptr
  2. 若使用了global.jsonresult会以global_json_path为 key 被调用,值为该文件路径;若未找到global.json,或其内容未影响解析(例如未指定版本),则不会以该 key 调用回调。

从源码实现看(hostfxr.cpp),除上述两个 key 外,当前版本还会调用requested_versionglobal_json_state两个额外的结果 key 向消费者传递请求版本与 global.json 的处理状态——这是文档未列出的演进细节,集成方若需跨版本兼容,建议对未知 key 保持忽略。

.NET Core 2.1+:hostfxr_get_available_sdks

typedef void (*hostfxr_get_available_sdks_result_fn)( int32_t sdk_count, const char_t *sdk_dirs[]); int32_t hostfxr_get_available_sdks( const char_t *exe_dir, hostfxr_get_available_sdks_result_fn result)

获取所有可用 SDK 的列表,按版本升序排列。

  • exe_dir— dotnet 可执行文件的路径;
  • result— 以目录路径数组返回 SDK 列表的回调。字符串数组及其元素仅在调用期间有效。

.NET Core 2.1+:hostfxr_get_native_search_directories

int32_t hostfxr_get_native_search_directories( const int argc, const char_t *argv[], char_t buffer[], int32_t buffer_size, int32_t *required_buffer_size)

基于指定应用,获取运行时的原生(native)搜索目录。

  • argc/argv— 命令行参数;
  • buffer— 用于填入原生搜索目录的缓冲区(含 null 终止符);
  • buffer_sizebuffer的大小,单位为char_t
  • required_buffer_size— 若buffer太小,此出参写入所需的最小缓冲区大小(含 null 终止符);否则置 0。

返回的目录列表以PATH_SEPARATOR分隔:Windows 上为分号(;),其他平台为冒号(:)。若buffer_size小于所需最小值,函数返回HostApiBufferTooSmall,且buffer保持不变。对应测试见 get_native_search_directories_test.cpp。

.NET Core 3.0+:hostfxr_set_error_writer

typedef void(*hostfxr_error_writer_fn)(const char_t *message); hostfxr_error_writer_fn hostfxr_set_error_writer(hostfxr_error_writer_fn error_writer)

设置用于报告错误消息的回调。默认未注册回调,错误写入标准错误流。

  • error_writer— 每次报告错误时调用的回调函数。置为nullptr时取消已注册的回调并恢复默认行为。

返回值是先前注册的回调(此时它已被注销),若此前没有注册则返回nullptr

关键线程模型与传播规则(与 hostfxr.h 中的注释一致):

  • 错误写入器按线程注册(thread-local):每个线程只能注册一个回调,后续注册会覆盖前一个;
  • 每次对错误写入器的调用相当于写一行(不含行结束符),一次失败可能触发多次调用;
  • hostfxr在运行过程中调用了hostpolicy的函数,错误写入器会在调用期间传播hostpolicy——即两层产生的错误都会经由同一个错误写入器上报。

.NET Core 3.0+:宿主上下文生命周期 API

这是自托管(self-hosting)场景的核心。完整语义与参数说明另见 native-hosting.md;以下为文档给出的 API 契约,并对照 hostfxr.h 中的实现细节补充。

初始化参数结构体:

typedef void* hostfxr_handle; struct hostfxr_initialize_parameters { size_t size; const char_t *host_path; const char_t *dotnet_root; };
hostfxr_initialize_for_dotnet_command_line
int hostfxr_initialize_for_dotnet_command_line( int argc, const char_t *argv[], const hostfxr_initialize_parameters *parameters, hostfxr_handle * host_context_handle);

为运行托管应用初始化托管组件。

  • argc/argv— 命令行参数(形如通过 dotnet 可执行文件传入的app.dll arg1 arg2);
  • parameters— 可选的附加参数;
  • host_context_handle— 初始化成功时接收一个标识已初始化宿主上下文的句柄值。

从 hostfxr.h 的声明注释可补充三点实现约束:该函数只解析命令行以确定要运行的应用、找到对应的.runtimeconfig.json.deps.json并准备加载运行时的全部信息,但不会加载运行时;它只支持“运行应用”的参数,不支持 SDK/CLI 命令;若托管组件已初始化则返回HostInvalidState

hostfxr_initialize_for_runtime_config
int hostfxr_initialize_for_runtime_config( const char_t *runtime_config_path, const hostfxr_initialize_parameters *parameters, hostfxr_handle *host_context_handle);

基于运行时配置文件(.runtimeconfig.json)初始化托管组件。

  • runtime_config_path— 要处理的.runtimeconfig.json文件路径;
  • parameters— 可选附加参数;
  • host_context_handle— 初始化成功时接收宿主上下文句柄。

根据 hostfxr.h 的注释,返回值除Success外还可能为Success_HostAlreadyInitialized(与已初始化的托管组件兼容)、Success_DifferentRuntimeProperties(运行时属性存在差异,需消费者自行判断可接受性)以及HostIncompatibleConfig(不兼容)。前两种成功码均视为初始化成功。该入口只处理框架的.deps.json,不处理与.runtimeconfig.json相邻的应用/组件级.deps.json

运行时属性(runtime properties)
int hostfxr_get_runtime_property_value( const hostfxr_handle host_context_handle, const char_t *name, const char_t **value);

按名称获取运行时属性值。

  • host_context_handle— 已初始化的宿主上下文。置为nullptr时,函数作用于进程中的第一个宿主上下文;
  • name— 要获取的运行时属性名;
  • value— 输出参数,指向属性值缓冲区的指针。

从源码注释看(hostfxr.h),value指向的缓冲区由宿主上下文所有,其生命周期保证到以下任一事件发生为止:对该上下文调用 run 方法、通过hostfxr_set_runtime_property_value修改属性、或调用hostfxr_close关闭上下文。

int hostfxr_set_runtime_property_value( const hostfxr_handle host_context_handle, const char_t *name, const char_t *value);

设置属性值。

  • host_context_handle— 已初始化的宿主上下文;
  • name— 要设置的运行时属性名;
  • value— 要设置的值。若属性在宿主上下文中已有值,本函数会覆盖它;置为nullptr且属性已有值时,属性被移除。

从 hostfxr.h 的约束看,设置属性仅支持在第一个宿主上下文、且运行时加载之前进行。

int hostfxr_get_runtime_properties( const hostfxr_handle host_context_handle, size_t * count, const char_t **keys, const char_t **values);

获取指定宿主上下文的全部运行时属性。

  • host_context_handle— 已初始化的宿主上下文。置为nullptr时作用于进程中的第一个宿主上下文;
  • count— in/out 参数,不可为nullptr。输入时表示keysvalues缓冲区的大小;输出时表示实际使用的条目数(即返回的属性个数);
  • keys— 充当“指向各属性 key 缓冲区指针”的数组的缓冲区;
  • values— 充当“指向各属性值缓冲区指针”的数组的缓冲区。

count小于所需最小缓冲区大小,或keys/valuesnullptr,函数返回HostApiBufferTooSmallkeysvalues保持不变(此时count会被写入可用属性数量,便于二次分配)。

hostfxr_run_app
int hostfxr_run_app(const hostfxr_handle host_context_handle);

运行由hostfxr_initialize_for_dotnet_command_line指定的应用。

  • host_context_handle— 已初始化宿主上下文的句柄。

应用执行完毕前不返回,执行后关闭 CoreCLR。成功执行时返回应用退出码,否则返回错误码。源码注释明确要求句柄必须来自hostfxr_initialize_for_dotnet_command_line(hostfxr.h)。

hostfxr_get_runtime_delegate
int hostfxr_get_runtime_delegate(const hostfxr_handle host_context_handle, hostfxr_delegate_type type, void ** delegate);

启动运行时并获取指定运行时功能的函数指针。

  • host_context_handle— 已初始化的宿主上下文;
  • type— 请求的运行时功能类型;
  • delegate— 成功时写入所请求运行时功能的原生函数指针。

委托类型枚举hostfxr_delegate_type定义在 hostfxr.h,包含hdt_com_activationhdt_load_in_memory_assemblyhdt_winrt_activationhdt_com_registerhdt_com_unregisterhdt_load_assembly_and_get_function_pointerhdt_get_function_pointerhdt_load_assemblyhdt_load_assembly_bytes

从源码注释看(hostfxr.h),存在按初始化入口划分的支持矩阵:由hostfxr_initialize_for_runtime_config初始化的上下文支持所有委托类型;由hostfxr_initialize_for_dotnet_command_line初始化的上下文(文档编写时点)仅支持hdt_load_assembly_and_get_function_pointerhdt_get_function_pointer

hostfxr_close
int hostfxr_close(const hostfxr_handle host_context_handle);

关闭宿主上下文。

  • host_context_handle— 要关闭的已初始化宿主上下文。

至此完成“initialize → 设置属性 → run_app / get_runtime_delegate → close”的完整宿主上下文生命周期。

源码中可见的后续演进 API

文档之外,hostfxr.h 与 hostfxr.cpp 还导出了若干后续版本新增的 API,供需要在现代宿主中查询环境或预解析框架的场景参考:

  • hostfxr_get_dotnet_environment_info:给定 dotnet 根目录(或全局默认位置),按版本升序返回可用 SDK 与按名称/版本升序返回的框架列表,结果结构为hostfxr_dotnet_environment_info(含hostfxr_versionhostfxr_commit_hash、SDK 数组、框架数组);
  • hostfxr_resolve_frameworks_for_runtime_config:针对指定.runtimeconfig.json解析框架,通过回调返回resolved_frameworksunresolved_frameworks两组结果(含请求版本与解析版本)。

从源码结构看,这些 API 沿用了相同的char_t编码约定与“字符串仅在回调期间有效”的生命周期规则。

三、Host Policy API

.NET Core 1.0+:corehost_load / corehost_main / corehost_unload

int corehost_load(host_interface_t *init)

初始化hostpolicy。它保存执行“启动 CoreCLR 所需全部处理”的信息,但不实际执行任何处理

  • init— 定义库应如何初始化的结构体(见下文“host_interface_t 结构体”)。

若库已初始化,本函数直接返回成功且不重新初始化init被忽略)。

int corehost_main(const int argc, const char_t* argv[])

运行一个应用程序。

  • argc/argv— 命令行参数。

应用执行完毕前不返回,执行后关闭 CoreCLR。成功时返回应用退出码,否则返回错误码。

int corehost_unload()

反初始化hostpolicy

.NET Core 2.1+:corehost_main_with_output_buffer

int corehost_main_with_output_buffer( const int argc, const char_t *argv[], char_t buffer[], int32_t buffer_size, int32_t *required_buffer_size)

运行宿主命令并返回其输出。要求此前已以init->host_command被设置的状态调用过corehost_load(init)。该函数运行于托管层,并不实际运行 CoreCLR

  • argc/argv— 命令行参数;
  • buffer— 用于填入输出的缓冲区(含 null 终止符);
  • buffer_sizebuffer的大小,单位为char_t
  • required_buffer_size— 若buffer太小,写入所需最小缓冲区大小(含 null 终止符);否则置 0。

buffer_size小于所需最小值,返回HostApiBufferTooSmall,且buffer保持不变。

.NET Core 3.0+:corehost_resolve_component_dependencies

typedef void(*corehost_resolve_component_dependencies_result_fn)( const char_t *assembly_paths, const char_t *native_search_paths, const char_t *resource_search_paths); int corehost_resolve_component_dependencies( const char_t *component_main_assembly_path, corehost_resolve_component_dependencies_result_fn result)

解析指定组件的依赖。

  • component_main_assembly_path— 组件的路径(主程序集);
  • result— 接收组件依赖解析结果的回调,分别收到程序集路径、原生搜索路径与资源搜索路径三个以PATH_SEPARATOR分隔的路径串。

完整机制(含.deps.json中组件条目的格式)见 host-component-dependencies-resolution.md,对应测试见 resolve_component_dependencies_test.cpp。

.NET Core 3.0+:corehost_set_error_writer

typedef void(*corehost_error_writer_fn)(const char_t *message); corehost_error_writer_fn corehost_set_error_writer(corehost_error_writer_fn error_writer)

设置用于报告错误消息的回调。默认未注册回调,错误写入标准错误流。

  • error_writer— 每次报告错误时调用的回调。置为nullptr时取消已注册回调并恢复默认行为。

返回值是先前注册的回调(此时已注销)或nullptr。错误写入器按线程注册,每个线程只能注册一个回调,后续注册覆盖前一个。与 hostfxr 侧不同,文档未描述 hostpolicy 独立注册时的传播语义——传播由 hostfxr 在调用期间完成(见上文 hostfxr 一节)。错误写入器的重定向实现在 redirected_error_writer.cpp,测试工具 error_writer_redirector.cpp 验证了该机制。

.NET Core 3.0+:corehost_context_contract 与 corehost_initialize

typedef void* context_handle; struct corehost_context_contract { size_t version; int (*get_property_value)( const char_t *key, const char_t **value); int (*set_property_value)( const char_t *key, const char_t *value); int (*get_properties)( size_t *count, const char_t **keys, const char_t **values); int (*load_runtime)(); int (*run_app)( const int argc, const char_t* argv[]); int (*get_runtime_delegate)( coreclr_delegate_type type, void** delegate); };

在已初始化的 hostpolicy 上执行操作的契约:

  • version— 结构体版本;
  • get_property_value— 获取宿主上下文属性的函数指针:
    • key— 要获取的属性的 key;
    • value— 指向所取得属性值缓冲区的指针;
  • set_property_value— 设置宿主上下文属性的函数指针:
    • key— 要设置的属性的 key;
    • value— 要设置的值;为nullptr时属性被移除;
  • get_properties— 获取宿主上下文全部属性的函数指针:
    • countkeysvalues的大小。若太小,将被写入所需大小;否则写入实际使用的大小;
    • keys— 填入属性 key 的缓冲区;
    • values— 填入属性值的缓冲区;
  • load_runtime— 加载 CoreCLR 的函数指针;
  • run_app— 运行应用的函数指针:
    • argc/argv— 命令行参数;
  • get_runtime_delegate— 获取 CoreCLR 功能委托的函数指针:
    • type— 请求的运行时功能类型;
    • delegate— 所请求运行时功能的函数指针。

从源码结构看,当前实现的 corehost_context_contract 在文档所示字段之后还追加了last_known_delegate_type(5.0 起),并同样用static_assert固定每个字段的偏移——这是“只追加、不重排”兼容策略的具体体现。coreclr_delegate_type枚举定义在同文件(corehost_context_contract.h),其取值与 hostfxr 侧的hostfxr_delegate_type一一对应(com_activationload_in_memory_assemblywinrt_activationcom_registercom_unregisterload_assembly_and_get_function_pointerget_function_pointerload_assemblyload_assembly_bytes)。

enum initialization_options_t { none = 0x0, wait_for_initialized = 0x1, get_contract = 0x2, }; int corehost_initialize(const corehost_initialize_request_t *init_request, int32_t options, corehost_context_contract *context_contract)

初始化 hostpolicy。它计算“启动或附加到 CoreCLR 所需的一切”(但不实际执行)。

  • init_request— 包含初始化请求信息的结构体。若 hostpolicy 尚未初始化,此处期望为nullptr;若已初始化,则不可为nullptr,本函数将用该结构体检查与先前初始化方式的兼容性;
  • options— 初始化选项:
    • wait_for_initialized— 等待通过另一请求完成的初始化结束;
    • get_contract— 获取已初始化 hostpolicy 的契约;
  • context_contract— 初始化成功时填入操作已初始化 hostpolicy 的契约。

init_request的结构体corehost_initialize_request_t在 corehost_context_contract.h 中定义为version+config_keys+config_valuesstrarr_t字符串数组对),同样带有偏移兼容断言。源码中该枚举还包含context_contract_version_set = 0x80000000位(corehost_context_contract.h),用于在输入时声明version字段已写入、指示可填充缓冲区的大小上限。

host_interface_t:跨层传递的初始化上下文

corehost_loadinit参数即 host_interface.h 中的host_interface_t。其关键字段包括:

  • version_lo/version_hi:版本信息,version_lo直接赋sizeof(),布局破坏性变更时递增HOST_INTERFACE_LAYOUT_VERSION_HI
  • config_keys/config_values:运行时配置键值对(strarr_t字符串数组);
  • fx_dir/fx_name/fx_ver:解析出的框架目录、名称与版本;
  • deps_file:依赖文件路径;probe_paths:探测路径集合;
  • patch_roll_forward/prerelease_roll_forward:补丁/预发布滚动升级策略;
  • host_mode:宿主模式(muxer即作为dotnet.exe调用、apphost即重命名后的应用宿主、libhost即 COM 激活或自托管等非 exe 场景);
  • host_commandcorehost_main_with_output_buffer所需的宿主命令;
  • host_info_host_path/host_info_dotnet_root/host_info_app_path:宿主路径、.NET 根目录与应用路径;
  • single_file_bundle_header_offset:单文件 Bundle 头偏移。

该结构体被显式 1 字节打包(#pragma pack(push, 1)),注释与static_assert链(host_interface.h)共同约束任何修改者:只追加字段、不改顺序与类型、为新增字段补断言。

四、错误码与缓冲区约定

文档中反复出现的HostApiBufferTooSmall属于统一的宿主错误码体系,完整定义见 error_codes.h,人读版文档为 host-error-codes.md。与本文 API 直接相关的条目包括:

错误码十六进制值含义
Success0操作成功
Success_HostAlreadyInitialized0x00000001初始化成功,但另一宿主上下文已初始化
Success_DifferentRuntimeProperties0x00000002初始化成功,但已初始化上下文的运行时属性与请求不同
InvalidArgFailure0x80008081一个或多个参数无效
InvalidConfigFile0x80008093.runtimeconfig.json文件无效
HostApiBufferTooSmall0x80008098提供给宿主 API 的缓冲区太小
SdkResolveFailure0x8000809b未能找到所请求的 SDK
HostInvalidState0x800080a3当前状态与请求的操作不兼容
HostPropertyNotFound0x800080a4hostfxr_get_runtime_property_value请求的属性不存在
HostIncompatibleConfig0x800080a5宿主配置与现有宿主上下文不兼容

注意error_codes.h中的判定宏STATUS_CODE_SUCCEEDED(status_code)定义为((int)(status_code)) >= 0——即错误码以 0x800080xx 高位区分失败,调用方只需检查非负即可判定成功。所有带输出缓冲区的 API(hostfxr_get_native_search_directoriescorehost_main_with_output_buffer等)统一遵循“缓冲区太小 → 返回HostApiBufferTooSmall、缓冲区不变、由required_buffer_size报告所需大小”的二次分配模式,集成方可以先传buffer_size = 0探测所需长度。

五、版本能力速查与源码对照

API引入版本(按文档)所属库源码位置
hostfxr_main.NET Core 1.0+hostfxrhostfxr.cpp
hostfxr_resolve_sdk(废弃).NET Core 2.0+hostfxrhostfxr.cpp
hostfxr_main_startupinfo.NET Core 2.1+hostfxrhostfxr.cpp
hostfxr_resolve_sdk2.NET Core 2.1+hostfxrhostfxr.cpp
hostfxr_get_available_sdks.NET Core 2.1+hostfxrhostfxr.cpp
hostfxr_get_native_search_directories.NET Core 2.1+hostfxrhostfxr.cpp
hostfxr_set_error_writer.NET Core 3.0+hostfxrhostfxr.cpp
hostfxr_initialize_for_dotnet_command_line.NET Core 3.0+hostfxrhostfxr.cpp
hostfxr_initialize_for_runtime_config.NET Core 3.0+hostfxrhostfxr.cpp
hostfxr_run_app.NET Core 3.0+hostfxrhostfxr.cpp
hostfxr_get_runtime_delegate.NET Core 3.0+hostfxrhostfxr.cpp
hostfxr_get/set/get_runtime_properties.NET Core 3.0+hostfxrhostfxr.cpp
hostfxr_close.NET Core 3.0+hostfxrhostfxr.cpp
corehost_load/corehost_main/corehost_unload.NET Core 1.0+hostpolicyhostpolicy.cpp
corehost_main_with_output_buffer.NET Core 2.1+hostpolicyhostpolicy.cpp
corehost_resolve_component_dependencies.NET Core 3.0+hostpolicyhostpolicy.h
corehost_set_error_writer.NET Core 3.0+hostpolicyhostpolicy.h
corehost_context_contract/corehost_initialize.NET Core 3.0+hostpolicycorehost_context_contract.h

六、集成要点小结

  1. 入口选择:只需“跑应用”用hostfxr_main/hostfxr_run_app;需要“在宿主中嵌入运行时、取函数指针”用hostfxr_initialize_for_runtime_config+hostfxr_get_runtime_delegate(此入口支持全部委托类型);需要“宿主命令输出”用corehost_main_with_output_buffer(需先以host_commandcorehost_load)。
  2. 缓冲区模式:所有带buffer/buffer_size/required_buffer_size的 API 均遵循“太小即HostApiBufferTooSmall且缓冲区不变”的约定,支持先探测后分配。
  3. 字符串生命周期:回调返回的字符串(SDK 目录、属性值等)均仅保证在回调/调用期间有效,需要留存请自行拷贝;host context 持有的属性缓冲区生命周期以 run、属性变更或hostfxr_close为界。
  4. 错误上报:生产宿主应注册 error writer 接管 stderr 输出;注意其线程局部特性,以及 hostfxr → hostpolicy 调用期间的传播行为。
  5. 兼容策略:hostfxr 各初始化 API 要求“同一进程内保持配置兼容”(Success_HostAlreadyInitialized/HostIncompatibleConfig语义);跨版本结构体兼容依赖host_interface_tcorehost_context_contract的“只追加 + 偏移断言”约束。

上述行为均可在仓库中直接验证:API 契约见 hostfxr.h 与 hostpolicy.h,实现见 fxr/hostfxr.cpp 与 hostpolicy/hostpolicy.cpp,测试入口在 nativehost 测试目录(含 mock 宿主、错误写入器重定向与依赖解析测试)。

【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 4:46:34

Moltbook 心跳任务不走默认模型通道,从 TaoToken 取 Key 行不行?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 4:44:16

VS Code调试Next.js全栈应用:从console.log到断点实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 4:41:43

STM32 CubeMX下FreeRTOS事件组源码级实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 4:38:29

Ubuntu stress 压力测试:CPU、内存与磁盘IO稳定性实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 4:37:16

Win10多用户同时远程登录配置全攻略:RDP Wrapper+组策略实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 4:34:30

十分钟部署 wewe-rss:微信公众号转 RSS 订阅完整指南

十分钟部署 wewe-rss:微信公众号转 RSS 订阅完整指南 【免费下载链接】wewe-rss 🤗更优雅的微信公众号订阅方式,支持私有化部署、微信公众号RSS生成(基于微信读书) 项目地址: https://gitcode.com/GitHub_Trending/w…

作者头像 李华