التدريب
الوحدة النمطية
أساليب الاستدعاء من مكتبة فئات .NET باستخدام لغة برمجة C# - Training
استخدم الوظائف في مكتبة فئات .NET عن طريق استدعاء الأساليب التي ترجع القيم وتقبل معلمات الإدخال والمزيد.
لم يعد هذا المتصفح مدعومًا.
بادر بالترقية إلى Microsoft Edge للاستفادة من أحدث الميزات والتحديثات الأمنية والدعم الفني.
Like all managed code, .NET applications are executed by a host. The host is responsible for starting the runtime (including components like the JIT and garbage collector) and invoking managed entry points.
Hosting the .NET runtime is an advanced scenario and, in most cases, .NET developers don't need to worry about hosting because .NET build processes provide a default host to run .NET applications. In some specialized circumstances, though, it can be useful to explicitly host the .NET runtime, either as a means of invoking managed code in a native process or in order to gain more control over how the runtime works.
This article gives an overview of the steps necessary to start the .NET runtime from native code and execute managed code in it.
Because hosts are native applications, this tutorial covers constructing a C++ application to host .NET. You will need a C++ development environment (such as that provided by Visual Studio).
You will also need to build a .NET component to test the host with, so you should install the .NET SDK. It includes the necessary headers and libraries to link with. As an example, on Windows with the .NET 8 SDK the files can be found in C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\8.0.4\runtimes\win-x64\native
.
Hosting the .NET runtime in .NET Core 3.0 and above is done with the nethost
and hostfxr
libraries' APIs. These entry points handle the complexity of finding and setting up the runtime for initialization and allow both launching a managed application and calling into a static managed method.
Prior to .NET Core 3.0, the only option for hosting the runtime was through the coreclrhost.h
API. This hosting API is obsolete now and should not be used for hosting .NET Core 3.0 and higher runtimes.
A sample host demonstrating the steps outlined in the tutorial below is available in the dotnet/samples GitHub repository. Comments in the sample clearly associate the numbered steps from this tutorial with where they're performed in the sample. For download instructions, see Samples and Tutorials.
Keep in mind that the sample host is meant to be used for learning purposes, so it is light on error checking and designed to emphasize readability over efficiency.
The following steps detail how to use the nethost
and hostfxr
libraries to start the .NET runtime in a native application and call into a managed static method. The sample uses the nethost
headers and library and the coreclr_delegates.h
and hostfxr.h
headers installed with the .NET SDK.
The nethost
library provides the get_hostfxr_path
function for locating the hostfxr
library. The hostfxr
library exposes functions for hosting the .NET runtime. The full list of functions can be found in hostfxr.h
and the native hosting design document. The sample and this tutorial use the following:
hostfxr_initialize_for_runtime_config
: Initializes a host context and prepares for initialization of the .NET runtime using the specified runtime configuration.hostfxr_get_runtime_delegate
: Gets a delegate for runtime functionality.hostfxr_close
: Closes a host context.The hostfxr
library is found using get_hostfxr_path
API from nethost
library. It is then loaded and its exports are retrieved.
// Using the nethost library, discover the location of hostfxr and get exports
bool load_hostfxr()
{
// Pre-allocate a large buffer for the path to hostfxr
char_t buffer[MAX_PATH];
size_t buffer_size = sizeof(buffer) / sizeof(char_t);
int rc = get_hostfxr_path(buffer, &buffer_size, nullptr);
if (rc != 0)
return false;
// Load hostfxr and get desired exports
void *lib = load_library(buffer);
init_fptr = (hostfxr_initialize_for_runtime_config_fn)get_export(lib, "hostfxr_initialize_for_runtime_config");
get_delegate_fptr = (hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate");
close_fptr = (hostfxr_close_fn)get_export(lib, "hostfxr_close");
return (init_fptr && get_delegate_fptr && close_fptr);
}
The sample uses the following includes:
#include <nethost.h>
#include <coreclr_delegates.h>
#include <hostfxr.h>
These files can be found at the following locations:
Or, if you have installed the .NET 8 SDK on Windows:
C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\8.0.4\runtimes\win-x64\native
The hostfxr_initialize_for_runtime_config
and hostfxr_get_runtime_delegate
functions initialize and start the .NET runtime using the runtime configuration for the managed component that will be loaded. The hostfxr_get_runtime_delegate
function is used to get a runtime delegate that allows loading a managed assembly and getting a function pointer to a static method in that assembly.
// Load and initialize .NET Core and get desired function pointer for scenario
load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t *config_path)
{
// Load .NET Core
void *load_assembly_and_get_function_pointer = nullptr;
hostfxr_handle cxt = nullptr;
int rc = init_fptr(config_path, nullptr, &cxt);
if (rc != 0 || cxt == nullptr)
{
std::cerr << "Init failed: " << std::hex << std::showbase << rc << std::endl;
close_fptr(cxt);
return nullptr;
}
// Get the load assembly function pointer
rc = get_delegate_fptr(
cxt,
hdt_load_assembly_and_get_function_pointer,
&load_assembly_and_get_function_pointer);
if (rc != 0 || load_assembly_and_get_function_pointer == nullptr)
std::cerr << "Get delegate failed: " << std::hex << std::showbase << rc << std::endl;
close_fptr(cxt);
return (load_assembly_and_get_function_pointer_fn)load_assembly_and_get_function_pointer;
}
The runtime delegate is called to load the managed assembly and get a function pointer to a managed method. The delegate requires the assembly path, type name, and method name as inputs and returns a function pointer that can be used to invoke the managed method.
// Function pointer to managed delegate
component_entry_point_fn hello = nullptr;
int rc = load_assembly_and_get_function_pointer(
dotnetlib_path.c_str(),
dotnet_type,
dotnet_type_method,
nullptr /*delegate_type_name*/,
nullptr,
(void**)&hello);
By passing nullptr
as the delegate type name when calling the runtime delegate, the sample uses a default signature for the managed method:
public delegate int ComponentEntryPoint(IntPtr args, int sizeBytes);
A different signature can be used by specifying the delegate type name when calling the runtime delegate.
The native host can now call the managed method and pass it the desired parameters.
lib_args args
{
STR("from host!"),
i
};
hello(&args, sizeof(args));
ملاحظات .NET
.NET هو مشروع مصدر مفتوح. حدد رابطًا لتقديم الملاحظات:
التدريب
الوحدة النمطية
أساليب الاستدعاء من مكتبة فئات .NET باستخدام لغة برمجة C# - Training
استخدم الوظائف في مكتبة فئات .NET عن طريق استدعاء الأساليب التي ترجع القيم وتقبل معلمات الإدخال والمزيد.