使用 CallConvMemberFunction 将基本类型映射到结构

Map fundamental type to struct using CallConvMemberFunction

提问人:Pavel Dubsky 提问时间:11/18/2023 更新时间:11/18/2023 访问量:36

问:

我有以下 C++ 代码:

struct IFoo
{
    virtual int __stdcall GetValue1(int value) = 0;
    virtual int __stdcall GetValue2(int value) = 0;
};

struct Foo : IFoo
{
    int __stdcall GetValue1(int value) override
    {
        return value + 1;
    }

    int __stdcall GetValue2(int value) override
    {
        return value + 1;
    }
};

extern "C" __declspec(dllexport) void CreateObject(IFoo** ptr)
{
    *ptr = new Foo;
}

extern "C" __declspec(dllexport) void FreeObject(IFoo* ptr)
{
    delete ptr;
}

和 C#:

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: DisableRuntimeMarshalling]

struct Result
{
    public readonly int value;

    public Result(int value)
    {
        this.value = value;
    }
}

unsafe struct IFoo : IFoo.Interface
{
    public readonly Vtbl<IFoo>* lpVtbl;

    public int GetValue1(int value)
    {
        return lpVtbl->GetValue1((IFoo*)Unsafe.AsPointer(ref this), value);
    }

    public Result GetValue2(int value)
    {
        return lpVtbl->GetValue2((IFoo*)Unsafe.AsPointer(ref this), value);
    }

    public interface Interface
    {
        int GetValue1(int value);
        Result GetValue2(int value);
    }

    public struct Vtbl<TSelf>
        where TSelf : unmanaged, Interface
    {
        public delegate* unmanaged[Stdcall, MemberFunction]<TSelf*, int, int> GetValue1;
        public delegate* unmanaged[Stdcall, MemberFunction]<TSelf*, int, Result> GetValue2;
    }
}

unsafe partial class Program
{
    [LibraryImport("CppLibrary")]
    private static partial void CreateObject(IFoo** ptr);

    [LibraryImport("CppLibrary")]
    private static partial void FreeObject(IFoo* ptr);

    public void Run()
    {
        IFoo* ptr;
        CreateObject(&ptr);
        Console.WriteLine(ptr->GetValue1(3));
        Console.WriteLine(ptr->GetValue2(3).value);
        FreeObject(ptr);
    }
}

我希望在输出中看到,但我看到.如果我更换一切正常。此外,删除还可以解决问题。我想更好地了解为什么会发生这种情况。我认为结构是可打印的,基本上可以放置而不是相同大小的类型。显然,我弄错了。有人可以向我解释为什么会发生这种行为,有没有办法保持为返回类型并同时拥有?4 44 0ResultintMemberFunctionResultResultMemberFunction

C# .net

评论


答: 暂无答案