我在C#中使用C方法时遇到了问题--它在C中编译和运行得很好,返回了设备ID的正确结果--但在windows中,这个函数似乎不能正确地构建字符串。在C中工作的源代码的代码如下,来自oblita.com上的interception.dll示例:
int main()
{
using namespace std;
InterceptionContext context;
InterceptionDevice device;
InterceptionStroke stroke;
wchar_t hardware_id[500];
raise_process_priority();
context = interception_create_context();
interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);
interception_set_filter(context, interception_is_mouse, INTERCEPTION_FILTER_MOUSE_LEFT_BUTTON_DOWN);
while(interception_receive(context, device = interception_wait(context), &stroke, 1) > 0)
{
    if(interception_is_keyboard(device))
    {
        InterceptionKeyStroke &keystroke = *(InterceptionKeyStroke *) &stroke;
        if(keystroke.code == SCANCODE_ESC) break;
    }
    size_t length = interception_get_hardware_id(context, device, hardware_id, sizeof(hardware_id));
    if(length > 0 && length < sizeof(hardware_id))
        wcout << hardware_id << endl;
    interception_send(context, device, &stroke, 1);
}
interception_destroy_context(context);
return 0;现在,我已经导入了C#中的DLL,它应该正确地涵盖了所有的变量转换:
    [DllImport("interception.dll", EntryPoint = "interception_get_hardware_id", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetHardwareID(IntPtr context, int device, ref StringBuilder idbuffer, uint buffer_size);下面是我试图触发的代码,以便在C#中获取设备ID:
     {
        IntPtr context;
        int device;
        Interception.Stroke stroke = new Interception.Stroke();
        context = Interception.CreateContext();
        Interception.SetFilter(context, Interception.IsKeyboard, Interception.Filter.All);
        StringBuilder hardwareID = new StringBuilder();
        while (Interception.Receive(context, device = Interception.Wait(context), ref stroke, 1) > 0)
        {
            int hardwareID_length = Interception.GetHardwareID(context, device, ref hardwareID, Convert.ToUInt32(hardwareID.Length));
            if (hardwareID_length > 0 && hardwareID_length < Convert.ToUInt32(hardwareID.Length))
            Console.WriteLine("ID result: ", hardwareID);
            Console.WriteLine("SCAN CODE: {0}/{1}", stroke.key.code, stroke.key.state);
            if (stroke.key.code == ScanCode.X)
            {
                stroke.key.code = ScanCode.Y;
            }
            Interception.Send(context, device, ref stroke, 1);
            // Hitting escape terminates the program
            if (stroke.key.code == ScanCode.Escape)
            {
                break;
            }
        }
        Interception.DestroyContext(context);
    }
}if语句中的块从不触发-它没有正确打印ID,我认为这意味着字符串生成器没有像C中的wchar_t那样正确填充。值是0,这意味着它从来没有通过指针提供正确的信息,对吧?我能做些什么来解决这个问题呢?任何帮助都是非常感谢的。
应该注意的是,scancode工作正常-它检测击键,甚至如预期的那样用y替换x。
发布于 2013-11-22 06:43:24
作为我自己挖掘和大量试验和错误的结果,下面是如何让它工作的方法:
{
[DllImport("interception.dll", EntryPoint = "interception_get_hardware_id", CallingConvention = CallingConvention.Cdecl)]
    public static unsafe extern int GetHardwareID(IntPtr context, int device, out void* idbuffer, uint buffer_size);
//Note the call is unsafe - because we're using the void* pointer.
{(inside an unsafe block of code)
void* hardwareID;
//call function as follows:
int result = Interception.GetHardwareID(context, device, out hardwareID, 5000);
//i use 5000 because it works. i'm sure there's better ways to do it but i don't want to spend another few months on figuring it out.
IntPtr hardwareConverted = new IntPtr(hardwareID);
//this marshals the void* into an IntPtr that you can play around with as normal, in managed memory.https://stackoverflow.com/questions/19896187
复制相似问题