我正在关注 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/