将C#委托传递给C ++ / CLI包装器

时间:2016-04-22 14:00:44

标签: 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#项目的委托。在上面链接的示例中,我只解释了如何从包装器中设置委托。但是如何从C#项目中设置委托?当我尝试从我的C#项目中调用setKeyCallback时,我收到错误Window.setKeyCallback(?) is not supported by the language

1 个答案:

答案 0 :(得分:3)

您似乎错过了指令的管理部分:

#pragma managed

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

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

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

在您的代码中,KEY_CALLBACK是一个非托管函数声明。因此,#34;不支持语言"。 C#方不能将其用作委托声明。

为了避免这种混乱,我自己始终保持我的C ++ \ CLI项目不受任何托管声明的影响,并在C ++ \ CLI包装器和C#端引用的附加C#类库中提供这些声明。

编辑:不要忘记在托管方法声明中的托管引用类型之后放置 ^ 符号,否则编译器将会出现错误' A委托此处不允许输入'。