首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++ / C#互操作-用于处理谓词的互操作定义

C++ / C#互操作-用于处理谓词的互操作定义
EN

Stack Overflow用户
提问于 2014-03-17 19:00:02
回答 2查看 205关注 0票数 1

因此,我试图为c++ API编写一个包装器,这样我就可以将它与C#一起使用。c++ api及其相关信息位于这里

因此,我试图从C++代码中与C# dll进行交互。我能够成功地做到这一点。但现在我正忙着想让某项功能正常工作。对C++中函数的工作调用的一个例子是:

代码语言:javascript
运行
复制
interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);

其中INTERCEPTION_FILTER_KEY_DOWN和INTERCEPTION_FILTER_KEY_DOWN由以下方法定义:

代码语言:javascript
运行
复制
typedef int (*InterceptionPredicate)(InterceptionDevice device);

enum InterceptionKeyState
{
    INTERCEPTION_KEY_DOWN             = 0x00,
    INTERCEPTION_KEY_UP               = 0x01,
...
};

    enum InterceptionFilterKeyState
    {
    INTERCEPTION_FILTER_KEY_DOWN             = INTERCEPTION_KEY_UP,
    INTERCEPTION_FILTER_KEY_UP               = INTERCEPTION_KEY_UP << 1,
};

interception_is_keyboard是可以传递到interception_set_filter中的各种谓词之一。谓词的功能是这样描述的:

interception_set_filter函数有三个参数,通信上下文、函数指针和所需的过滤器。第二个参数,函数指针,是一个设备选择谓词,该函数接收设备id (如INTERCEPTION_KEYBOARD(0)、INTERCEPTION_KEYBOARD(1)等)作为参数,如果传递的设备id是必须通过所选过滤器过滤的设备之一,则返回true;对于不通过此过滤器过滤的设备,返回false。因此,interception_set_filter的工作方式是扫描所有可能的设备,并使用所提供的谓词作为标准,以了解所提供的筛选器应该应用于哪些设备。

此外,在代码中定义了实现此谓词interception_is_keyboard的签名的方法,因此:

代码语言:javascript
运行
复制
int interception_is_keyboard(InterceptionDevice device)
{
    return device >= INTERCEPTION_KEYBOARD(0) && device <= INTERCEPTION_KEYBOARD(INTERCEPTION_MAX_KEYBOARD - 1);
}

.h文件中interception_set_filter的定义是:

代码语言:javascript
运行
复制
void ITERCEPTION_API interception_set_filter(InterceptionContext context, InterceptionPredicate predicate, InterceptionFilter filter);

其中ITERCEPTION_API是:

代码语言:javascript
运行
复制
#define ITERCEPTION_API __declspec(dllimport)

因此,我的问题是,如何设置才能调用interception_set_filter并使用来自C#应用程序(托管代码)的谓词interception_is_keyboard?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-17 19:18:03

可以使用C#委托为PInvoke参数创建函数指针。这里也问了一个类似的问题。

编辑过滤器由枚举或Int32提供。所以这是众所周知的。

编辑2汉斯帕桑特评论说,我不需要使用[MarshalAs(UnmanagedType.FunctionPtr)],它假设(默认)我学到了一些新的东西,谢谢汉斯)。他还指出,“确保委托保持引用,以便在本机代码进行回调时不能收集垃圾”。非常感谢。

编辑3我从您提供的链接中读到了一点,显然context是一个void*。我假设您还需要PInvoke interception_create_context来获取您的void*,然后传递该指针。假设你有一个有效的指针,我已经相应地调整了答案。

而且,我不知道您在哪里定义InterceptionDevice,我现在假设是Int32

我的C#代表应该如下所示:

代码语言:javascript
运行
复制
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void InterceptionPredicateType(Int32 device);

[DllImport("your.dll")]
public extern static int interception_is_keyboard(IntPtr context, InterceptionPredicateType predicate, Int32 filter);
票数 1
EN

Stack Overflow用户

发布于 2014-03-17 21:10:37

已经有了一个C#包装器这里。作者倾弃是因为他更喜欢使用它,在Clojure中代替。有人还做了Python包装器,我也听说过其他人。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22463061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档