因此,我试图为c++ API编写一个包装器,这样我就可以将它与C#一起使用。c++ api及其相关信息位于这里。
因此,我试图从C++代码中与C# dll进行交互。我能够成功地做到这一点。但现在我正忙着想让某项功能正常工作。对C++中函数的工作调用的一个例子是:
interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);其中INTERCEPTION_FILTER_KEY_DOWN和INTERCEPTION_FILTER_KEY_DOWN由以下方法定义:
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的签名的方法,因此:
int interception_is_keyboard(InterceptionDevice device)
{
    return device >= INTERCEPTION_KEYBOARD(0) && device <= INTERCEPTION_KEYBOARD(INTERCEPTION_MAX_KEYBOARD - 1);
}.h文件中interception_set_filter的定义是:
void ITERCEPTION_API interception_set_filter(InterceptionContext context, InterceptionPredicate predicate, InterceptionFilter filter);其中ITERCEPTION_API是:
#define ITERCEPTION_API __declspec(dllimport)因此,我的问题是,如何设置才能调用interception_set_filter并使用来自C#应用程序(托管代码)的谓词interception_is_keyboard?
发布于 2014-03-17 19:18:03
可以使用C#委托为PInvoke参数创建函数指针。这里也问了一个类似的问题。
编辑过滤器由枚举或Int32提供。所以这是众所周知的。
编辑2汉斯帕桑特评论说,我不需要使用[MarshalAs(UnmanagedType.FunctionPtr)],它假设(默认)我学到了一些新的东西,谢谢汉斯)。他还指出,“确保委托保持引用,以便在本机代码进行回调时不能收集垃圾”。非常感谢。
编辑3我从您提供的链接中读到了一点,显然context是一个void*。我假设您还需要PInvoke interception_create_context来获取您的void*,然后传递该指针。假设你有一个有效的指针,我已经相应地调整了答案。
而且,我不知道您在哪里定义InterceptionDevice,我现在假设是Int32。
我的C#代表应该如下所示:
[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);发布于 2014-03-17 21:10:37
已经有了一个C#包装器这里。作者倾弃是因为他更喜欢使用它,在Clojure中代替。有人还做了Python包装器,我也听说过其他人。
https://stackoverflow.com/questions/22463061
复制相似问题