C++;/C#Interop-用于处理谓词的Interop定义 所以我试着在C++ API上写一个包装器,这样我就可以用C语言来使用它。C++ API及其相关信息位于.< >我尝试从C++代码中与C++ DLL进行交互。我能够在一定程度上成功地做到这一点。但现在,我正绞尽脑汁试图让某个函数正常工作。C++中函数调用的一个例子是: interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);

C++;/C#Interop-用于处理谓词的Interop定义 所以我试着在C++ API上写一个包装器,这样我就可以用C语言来使用它。C++ API及其相关信息位于.< >我尝试从C++代码中与C++ DLL进行交互。我能够在一定程度上成功地做到这一点。但现在,我正绞尽脑汁试图让某个函数正常工作。C++中函数调用的一个例子是: interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);,c#,c++,interop,C#,C++,Interop,其中,拦截过滤键关闭和拦截过滤键关闭的定义如下: typedef int (*InterceptionPredicate)(InterceptionDevice device); enum InterceptionKeyState { INTERCEPTION_KEY_DOWN = 0x00, INTERCEPTION_KEY_UP = 0x01, ... }; enum InterceptionFilterKeyS

其中,拦截过滤键关闭和拦截过滤键关闭的定义如下:

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,
};
其中ITERCEPTION_API为:

#define ITERCEPTION_API __declspec(dllimport)

所以,我的问题是,我如何设置才能调用拦截集过滤器并使用C#app(托管代码)中的谓词拦截键盘


您可以使用C#委托为PInvoke参数创建函数指针。有人提出了类似的问题

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

编辑2Hans Passant评论说我不需要使用
[Marshallas(UnmanagedType.FunctionPtr)]
,假设(默认)我学到了一些新东西,谢谢Hans)。他还特别指出,“确保委托保持被引用状态,以便在本机代码进行回调时不会被垃圾回收”。多谢各位

edit3我从您提供的链接中读了一些内容,显然
context
是一个
void*
。我假设您还必须PInvoke
拦截\u创建\u上下文
来获取您的
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);

已经有一个C#包装器了。作者选择了它,因为他更喜欢利用它。有人也做了一个,我听说过其他人。

第一个和第三个参数(上下文和筛选器)是什么类型?什么类型是拦截设备?好的,过滤器来自枚举-我现在看到了。不需要[Marshallas]属性。您需要警告OP,他需要确保委托保持被引用状态,以便在本机代码进行回调时不会被垃圾回收。@HansPassant非常感谢您提供的信息!谢谢你们两位。拦截设备的定义是typedef int拦截设备;当您谈到确保委托保持被引用时,我想您的意思是不要让它超出范围?@JayGee不完全是,部分是。范围和资源解除分配在托管世界中的工作方式不同。当一个对象超出c#中的作用域时,它有资格被释放,但垃圾收集器可以在空闲时进行释放(出于优化目的)。为了安全起见,最好假设数据在超出范围时发布,但技术上可能会延迟。通常在c#中,当您传递引用(甚至是函数的引用)时,对象会被引用计数并保持加载状态,但在封送时,您将失去这种保护。非常感谢。我将研究他的代码,看看他是如何处理互操作声明的,等等。谢谢你们把截取放在一起。
#define ITERCEPTION_API __declspec(dllimport)
[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);