与 nethost.dll 的互操作失败,不知道为什么

问题描述 投票:0回答:1

我正在尝试与 nethost.dll 进行互操作,但它不断返回一个非零整数,这表明失败。我对 C# 中的本机互操作不太熟悉,所以我很难诊断问题。

互操作代码如下,使用 ClangSharpPInvokeGenerator 生成:

[DllImport("runtimes/win-x64/nethost.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
public static extern int get_hostfxr_path(ushort* buffer, nuint* buffer_size, get_hostfxr_parameters* parameters);

public unsafe partial struct get_hostfxr_parameters
{
    public nuint size;

    public ushort* assembly_path;

    public ushort* dotnet_root;
}

互操作代码由下面的代码调用,基于Microsoft 的托管指南中提供的示例:

ushort* ptr = stackalloc ushort[ushort.MaxValue];
nuint* size = stackalloc nuint[ushort.MaxValue / sizeof(ushort*)];
int i = nethost.get_hostfxr_path(ptr, size, null);

返回后,传递的缓冲区不会更改调用

get_hostfxr_path
之前设置的值。整数返回为
-2147450728

我尝试将 PInvoke 的

buffer
buffer_size
参数更改为
IntPtr
。它仍然有效,但错误代码没有改变。我还查看了其他开源项目中存在的互操作代码,但我无法找到另一种编写我的代码的方法。

我到底错过了什么?我真的很感激你的帮助,我已经超出了我的能力范围并且陷入困境。

c# runtime interop hosting pinvoke
1个回答
0
投票

您收到的错误是 HostApiBufferTooSmall,因为您传递了无效大小的缓冲区。您的

size
参数是指向包含垃圾的数组的指针。你可以这样修复它:

ushort* ptr = stackalloc ushort[ushort.MaxValue];
nuint* size = stackalloc nuint[1];
*size = ushort.MaxValue;
var hr = get_hostfxr_path(ptr, size, null);

此外,您可以使用

ushort
,但使用 .NET 的自然
char
string
类型更容易,这应该可以工作:

const int bufferSize = 2048; // or ushort.MaxValue but seems too large
var str = new string('\0', bufferSize);
var size = bufferSize / sizeof(char);
fixed (char* buffer = str)
{
    var hr = get_hostfxr_path(buffer, (nuint*)&size, null);
    if (hr >= 0)
    {
        str = str[..(size - 1)]; // final string
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.