我遵循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
。
答案 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委托此处不允许输入'。