c# - 将 C# 委托(delegate)传递给 C++/CLI 包装器

标签 c# c++ callback delegates

我正在关注 this使用 C# 委托(delegate)作为 C++ 回调的示例。

我的包装看起来像这样:

// GLFWWrapper.h

#pragma once

using namespace System;

namespace GLFWWrapper {

    typedef void(__stdcall *KEY_CALLBACK)(int, int, int, int);

    public ref class Window {
        public:
            void setKeyCallback(KEY_CALLBACK fp);
            static KEY_CALLBACK csharpKeyCallback;
        ...
    };
}  

// GLFWWrapper.cpp

#include "stdafx.h"

#include "GLFWWrapper.h"

namespace GLFWWrapper {

    void cppKeyCallback(GLFWwindow * window, int key, int scancode, int action, int mods) {
        if (Window::csharpKeyCallback) {
            Window::csharpKeyCallback(key, scancode, action, mods);
        }
    }

    void Window::setKeyCallback(KEY_CALLBACK fp) {
        csharpKeyCallback = fp;
    }

    ...
}

cppKeyCallback函数是我在另一个函数(glfwSetKeyCallback(m_ptr, cppKeyCallback);)中设置的回调。 csharpKeyCallback 应该是我的 C# 项目的委托(delegate)。在我上面链接的例子中,它只解释了我如何从我的包装器内部设置一个委托(delegate)。但是如何从我的 C# 项目中设置委托(delegate)呢?当我尝试从我的 C# 项目调用 setKeyCallback 时,出现错误 Window.setKeyCallback(?) is not supported by the language

最佳答案

您似乎缺少指令的托管部分:

#pragma managed

public delegate void keyCallback(int, int, int, int);

void Window::setKeyCallback(keyCallback^ fp) {
    csharpKeyCallback = fp;
}

为了将对函数实例(委托(delegate))的引用从 C# 传递到 C++\CLI,您需要对其进行声明,即声明托管委托(delegate)。这可以在 C# 或 C++\CLI 中完成。

在您的代码中,KEY_CALLBACK 是一个非托管函数声明。因此它是“不受语言支持”。 C# 端不能将其用作委托(delegate)声明。

为了避免这样的困惑,我自己总是让我的 C++\CLI 项目远离任何托管声明,并在从 C++\CLI 包装器和 C# 端引用的附加 C# 类库中提供这些声明。

编辑:不要忘记在托管方法声明中的托管引用类型后面加上 ^ 符号,否则编译器会报错 'A delegate type is not此处允许'。

关于c# - 将 C# 委托(delegate)传递给 C++/CLI 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36795878/

相关文章:

c++ - STL 中的迭代器指针如何工作

c++ - 如何正确地将值从数组复制到 vector ?

c++ - Visual Studio 2012 和 2010 - kernel32.lib, windows.h

javascript - 将函数引用作为回调函数传递

javascript - 我如何(真的!)使 JavaScript 异步调用同步(在 Chrome 上)?

c# - 使用 .NET 2.0 的 System.BadImageFormatException

c# - 扩展 Entity Framework 将列添加到 Identity Server 4 客户端表

c# - 如何检查每个列表成员的属性值是否相同

c# - 在 WinRT 中加载图像文件

keras - 在回调 ModelCheckpoint 上使用模型保存历史记录