[英]cannot fake a managed callback from c++ (cannot cast from 'void (GenFlowcacheTests::*)(int)' to 'void(*)(int)' via static_cast)
我定義了一個指向托管 function 的指針:
typedef void(__stdcall* CounterCallback)(int count);
然后我將定義一個 c++ 方法:
void CBSpline::GenFlowcache(/*few irrelevant parameters*/, CounterCallback func)
{/*instructions*/}
在單元測試中,我想用原生 function 測試GenFlowcache
。
int _flowCount{};
auto Increment(int value) -> void { _flowCount = value; }
TEST_METHOD(Gen_CallbackTest)
{
// ...
sut.GenFlowcache(/**/, static_cast<CounterCallback>(GenFlowcacheTests::Increment));
}
但我找不到轉換方法的方法:
無法通過 static_cast 從 'void (GenFlowcacheTests::*)(int)' 轉換為 'void(*)(int)'
( 編譯器錯誤 C2440 )
如何將本機 function (方法,lambda 等)作為CounterCallback
傳遞?
它對問題沒有用,但托管部分是這樣的:
public delegate void CounterCallback(int value);
public static class CBSplines
{
[DllImport("CubicBSplines.dll", CallingConvention = CallingConvention.StdCall)]
internal static extern unsafe void GenFlowcache(IntPtr p, BroxParam* broxParam, IntPtr sourceDir, IntPtr targetDir, CounterCallback counter);
}
然后在托管 class 中:
private CounterCallback _counter;
public unsafe void GenerateFlowcache(BroxParam parameters, string sourceDir, string targetLocalDir)
{
if (_counter is null)
_counter = CounterUpdated;
if (!Directory.Exists(targetLocalDir))
Directory.CreateDirectory(targetLocalDir);
var strSrcDir = Marshal.StringToHGlobalAuto(sourceDir);
var strTgtDir = Marshal.StringToHGlobalAuto(targetLocalDir);
CBSplines.GenFlowcache(_ptr, ¶meters, strSrcDir, strTgtDir, _counter);
Marshal.FreeHGlobal(strSrcDir);
Marshal.FreeHGlobal(strTgtDir);
}
protected void CounterUpdated(int value) => FlowcacheCounter = value;
回到本機:
#ifndef Pinvoke
#define Pinvoke extern "C" __declspec(dllexport)
#endif
Pinvoke auto GenFlowcache(CBSpline* p, BroxParam* param, const wchar_t* sourceDir, const wchar_t* targetDir, CounterCallback func)
-> void { p->GenFlowcache(param, sourceDir, targetDir, func); }
正如約翰所指出的:
您可以傳遞 function 或 static 方法類型
void(int)
您也可以傳遞具有相同簽名的非捕獲 lambda ,並且您不能通過 class 方法,但是它是鍵入的
我可以通過一個全局function:
int _flowCount{};
auto Increment(int value) -> void { _flowCount = value; }
將在測試方法中通過:
sut.GenFlowcache(/**/, (CounterCallback)Increment);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.