gpt4 book ai didi

c# - 如何将 C++ std::future 返回值适配为 C# System.Threading.Tasks.Task?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:42:19 26 4
gpt4 key购买 nike

我正在包装一个要从 .NET 使用的 C++ 库。 C++ API 中有返回 std::future 的函数。我想让 .NET 代理类返回 System.Threading.Tasks.Task

我想在 C++ 端添加一个替代方法,除了方法参数之外,它还会接受一个函数指针。然后我可以启动一个新线程(例如使用 std::async)并等待 std::future::get。一旦 std::future::get 返回,我就可以调用传入的函数指针。在 C# 方面,我会将指针传递给将完成返回的任务的函数。像这样的东西:

Task CallCpp(int a, int b) {
TaskCompletionSource<int> tcs;
Action callback = () => tcs.SetResult(0);
IntPtr callbackPtr = Marshal.GetFunctionPointerForDelegate(callback);
CppMethod(callbackPtr, a, b);
return tcs.Task;
}
[DllExport]
external void CppMethod(IntPtr callback, int a, int b);
void CppMethod(void (*callback)(), int a, int b) {
std::future f = realmethod(a, b);
std::async([&]{ f.get; callback(); });
}

std::future realmethod(int a, int b);

(是的,代码存在内存管理问题。尽管如此应该足以理解这个想法)

最佳答案

编码异步完成或失败是相对容易的部分。我个人会使用在 C# 中实现的 COM 接口(interface),标记为 [InterfaceType( ComInterfaceType.InterfaceIsIUnknown )],有 2 个方法,如 setCompleted()setFailed( HRESULT status ),并在我开始任务时传递它,但这是个人喜好问题。

问题是缺少C++多线程实现。

Boost 在这方面更好,它的 future 类有 then method that can be used在不阻塞线程的情况下传播状态。

目前,标准 C++ future 不提供任何可比性。我认为你运气不好。

如果您可以修改该 C++ 库,将 API 更改为更有意义的内容,即可以以非阻塞方式通知完成。


没有 COM,生命周期管理很复杂。在您启动异步任务之后但在它完成之前,C# 端的某个人需要保留该函数指针。这是一个可能的解决方案,请注意它如何使用 GCHandle 使回调比任务更有效:

[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
delegate void pfnTaskCallback( int hResult );

[DllImport( "my.dll" )]
static extern void launch( [MarshalAs( UnmanagedType.FunctionPtr )] pfnTaskCallback completed );

public static async Task runAsync()
{
var tcs = new TaskCompletionSource<bool>();
pfnTaskCallback pfn = delegate ( int hr )
{
if( hr >= 0 ) // SUCEEDED
tcs.SetResult( true );
else
tcs.SetException( Marshal.GetExceptionForHR( hr ) );
};
var gch = GCHandle.Alloc( pfn, GCHandleType.Normal );

try
{
launch( pfn );
await tcs.Task;
}
finally
{
gch.Free();
}
}

关于c# - 如何将 C++ std::future 返回值适配为 C# System.Threading.Tasks.Task?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56152684/

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