错误C3352(指定的函数与委托类型不匹配)

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

我知道这个错误消息有很多答案,但我未能找到解决我的问题的方法。我正在玩从非托管 C++ 通过 C++/CLI 到 C# 的函数调用。棘手的部分是我想将 C 回调函数指针向下传递到函数参数列表中的 C# 代码,然后从 C# 代码中调用此回调。它“原则上”是有效的,但有一个问题让我感到困惑。 (使用 Visual Studio 2022 17.6.5)

这个 C# 类被编译成程序集:

namespace CsWorker
{
    public class CsWorkerClass
    {
        public delegate int Callback();
        public int DoSomething(int i, Callback cb)
        {
            return i+cb();
        }
    }
}

我围绕程序集创建了一个 C++/CLI 包装类,该类被编译成单独的 DLL:

(头文件WrapperClass.h)

class WorkerClass;

class __declspec(dllexport) WrapperClass
{
public:
    using tCallback = int (*)(void);
    WrapperClass();
    ~WrapperClass();
    int DoSomething(int i, tCallback cb);
private:
    WorkerClass* m_pWorker{};
};

(实现文件WrapperClass.cpp)

#include "WrapperClass.h"
#include <msclr/auto_gcroot.h>
#include <msclr/marshal_cppstd.h>

using namespace System::Runtime::InteropServices;
using namespace CsWorker;

class WorkerClass
{
public:
    static int MyCallback()
    {
        return 77;
    }
    int DoSomething(int i, int(*cb)(void))
    {
        // The static_assert is not triggered
        static_assert(std::is_same_v<decltype(cb), decltype(&MyCallback)>);
        // The following line compiles
        /*return*/ m_pWorker->DoSomething(i, gcnew CsWorker::CsWorkerClass::Callback(&MyCallback));
        // This line doesn't compile
        // error C3352: 'int (__cdecl *__cdecl cb)(void)': the specified function does not match the delegate type 'int (void)'
        return m_pWorker->DoSomething(i, gcnew CsWorker::CsWorkerClass::Callback(cb));
    }
    msclr::auto_gcroot<CsWorkerClass^> m_pWorker{};
};

WrapperClass::WrapperClass()
{
    m_pWorker = new WorkerClass;
    m_pWorker->m_pWorker = gcnew CsWorkerClass;
}

WrapperClass::~WrapperClass()
{
    delete m_pWorker;
}

int WrapperClass::DoSomething(int i, tCallback cb)
{
    return m_pWorker->DoSomething(i, cb);
}

当两个参数的类型相同时,为什么通过

&MyCallback
编译的行和通过
cb
的行会产生错误?将
int(void)
函数转换为
int(void)
委托有什么问题?

c# c++-cli
1个回答
0
投票

一位同事向我推荐了 CodeProject 上的文章 C++/CLI:在委托中存储 Lambda,它为我的问题提供了解决方案。说实话,我并不声称理解它,但它确实有效!

© www.soinside.com 2019 - 2024. All rights reserved.