gpt4 book ai didi

c# - 我能否将 System.Object 编码为指向 C 的不可访问指针,然后返回到 C#?

转载 作者:行者123 更新时间:2023-11-30 15:06:10 25 4
gpt4 key购买 nike

在 C 中,我有一个函数,它注册一个回调和一个状态对象,然后在每次调用时将状态对象传递给回调,很像 EventHandler<EventArgs>在 C# 中工作。我在 C# 中有一个类,它向 C 函数注册了一个托管回调,目前通过了 IntPtr.Zero我根本不使用它,因为我还没有找到将托管对象引用传递给 C 并将其返回给 C# 的良好而干净的方法。

我不希望托管对象可以在 C 中访问,我只想将它传递给 C,并让它在每次从 C 调用时传回(逐字)给托管回调。

基本上是在寻找“正确”的方法。

这是我的 callack 代表:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.SysInt)]
internal delegate IntPtr LuaAllocator(
[In, MarshalAs(UnmanagedType.AsAny)] object args,
[In, MarshalAs(UnmanagedType.SysInt)] IntPtr ptr,
[In, MarshalAs(UnmanagedType.SysInt)] IntPtr originalSize,
[In, MarshalAs(UnmanagedType.SysInt)] IntPtr newSize);

这里是电流 DllImport我在做:

    [DllImport(DllName, EntryPoint = "lua_newstate", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.SysInt)]
public static extern IntPtr NewState(
[In, MarshalAs(UnmanagedType.FunctionPtr)] LuaAllocator allocator,
[In, MarshalAs(UnmanagedType.AsAny)] object args);

我现在遇到的错误是:

MarshalDirectiveException was unhandled: Cannot marshal 'parameter #1': AsAny cannot be used on return types, ByRef parameters, ArrayWithOffset, or parameters passed from unmanaged to managed.

如果我将委托(delegate)的第一个参数保留为 IntPtr,这个错误就会消失并使用 MarshalAs.SysInt但我无法重建托管对象,但我得到的值不是 IntPtr.Zero这很好奇并且可能有用。

最佳答案

我找到了解决办法。 HandleRef 评论将我指向了我已经熟悉但从未使用过的 GCHandle。通过从要编码的对象创建非固定 GCHandle,您可以调用静态 GCHandle.ToIntPtr(GCHandle) 方法来获取 IntPtr 代表那个特定的句柄。在回调中,我调用了 GCHandle.FromIntPtr(IntPtr) 来重新获取句柄,然后从 GCHandle.Target 中检索了 System.Object属性(property)。

以下是设置回调和状态对象的方法:

// Omitted
string test = "This is a test string.";
GCHandle handle = GCHandle.Alloc(test, GCHandleType.Normal);
LuaCore.NewState(allocateCallback, GCHandle.ToIntPtr(handle));
// Omitted

下面是如何在回调中使用它:

private IntPtr Allocate(IntPtr sender, IntPtr ptr, IntPtr originalSize, IntPtr newSize)
{
GCHandle handle = GCHandle.FromIntPtr(sender);
string test = handle.Target as string;

// Omitted
}

关于c# - 我能否将 System.Object 编码为指向 C 的不可访问指针,然后返回到 C#?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8173986/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com