When I load the DLL path of a C# Class Library DLL, it either doesn't find it or the functions are not recognized or loaded. Even though it's the same runtime (i.e., .NET 9.0), I only get the status code as an error. Can someone explain why this is not working? I would be very grateful.
C++ Code:
#include <windows.h>
#include <iostream>
#include <string>
#include "hostfxr.h"
#include "coreclr_delegates.h"
typedef int (*component_entry_point_fn)(void* arg, int32_t arg_size_in_bytes);
void* load_library(const char_t* path)
{
return LoadLibraryW(path);
}
void* get_export(void* lib, const char* name)
{
return GetProcAddress((HINSTANCE)lib, name);
}
bool load_hostfxr(const std::wstring& runtime_config_path, hostfxr_initialize_for_runtime_config_fn& init_fn, hostfxr_get_runtime_delegate_fn& get_delegate_fn, hostfxr_close_fn& close_fn)
{
std::wstring hostfxr_path = L"C:\\Program Files\\dotnet\\host\\fxr\\9.0.1\\hostfxr.dll";
void* lib = load_library(hostfxr_path.c_str());
if (!lib) return false;
init_fn = (hostfxr_initialize_for_runtime_config_fn)get_export(lib, "hostfxr_initialize_for_runtime_config");
get_delegate_fn = (hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate");
close_fn = (hostfxr_close_fn)get_export(lib, "hostfxr_close");
return init_fn && get_delegate_fn && close_fn;
}
bool create_host_context(const std::wstring& runtime_config_path, hostfxr_initialize_for_runtime_config_fn init_fn, hostfxr_handle& ctx)
{
hostfxr_initialize_parameters params{ sizeof(hostfxr_initialize_parameters), nullptr, nullptr };
return init_fn(runtime_config_path.c_str(), ¶ms, &ctx) == 0;
}
bool get_function_pointer(hostfxr_handle ctx, hostfxr_get_runtime_delegate_fn get_delegate_fn, load_assembly_and_get_function_pointer_fn& func_ptr)
{
return get_delegate_fn(ctx, hdt_load_assembly_and_get_function_pointer, (void**)&func_ptr) == 0;
}
int main()
{
std::wstring runtime_config = L"C:\\Users\\Reversed Codes\\Desktop\\testnative_cs\\bin\\Release\\net9.0\\win-x64\\publish\\testnative_cs.runtimeconfig.json";
std::wstring dll_path = L"C:\\Users\\Reversed Codes\\Desktop\\testnative_cs\\bin\\Release\\net9.0\\win-x64\\publish\\testnative_cs.dll";
hostfxr_initialize_for_runtime_config_fn init_fn;
hostfxr_get_runtime_delegate_fn get_delegate_fn;
hostfxr_close_fn close_fn;
if (!load_hostfxr(runtime_config, init_fn, get_delegate_fn, close_fn))
{
std::wcerr << L"Fehler: hostfxr konnte nicht geladen werden." << std::endl;
return -1;
}
hostfxr_handle ctx;
if (!create_host_context(runtime_config, init_fn, ctx))
{
std::wcerr << L"Fehler: hostfxr-Initialisierung fehlgeschlagen." << std::endl;
return -1;
}
load_assembly_and_get_function_pointer_fn load_assembly_fn;
if (!get_function_pointer(ctx, get_delegate_fn, load_assembly_fn))
{
std::wcerr << L"Fehler: Konnte Delegate-Funktion nicht abrufen." << std::endl;
return -1;
}
void* method_ptr;
int result = load_assembly_fn(
dll_path.c_str(),
L"ManagedLibrary.HelloWorld",
L"SayHello",
UNMANAGEDCALLERSONLY_METHOD,
nullptr,
&method_ptr);
std::cout << "Result: " << result << std::endl;
if (result != 0)
{
std::wcerr << L"Fehler: Methode konnte nicht geladen werden." << std::endl;
return -1;
}
auto managed_entry = (component_entry_point_fn)method_ptr;
managed_entry(nullptr, 0);
close_fn(ctx);
return 0;
}
C# Code:
using System;
using System.Runtime.InteropServices;
namespace testnative_cs
{
public class HelloWorld
{
[UnmanagedCallersOnly]
public static int SayHello(IntPtr arg, int arg_size)
{
Console.WriteLine("Hallo aus C#!");
return 0;
}
}
}
C# .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
output:
Result: -2146233054
Fehler: Methode konnte nicht geladen werden.
C:\Users\Reversed Codes\source\repos\TestNative\x64\Debug\TestNative.exe (Prozess "34156") wurde mit Code "-1" (0xffffffff) beendet.
Um die Konsole beim Beenden des Debuggens automatisch zu schließen, aktivieren Sie "Extras" > "Optionen" > "Debuggen" > "Konsole beim Beenden des Debuggings automatisch schließen".
Drücken Sie eine beliebige Taste, um dieses Fenster zu schließen.
I am developing server software in C++ and want to add C# plugin support, but I am stuck on this function. I hope someone can fix it or provide a tip.