c# - 将 C dll 和方法导入到 c# 中

标签 c# c pointers dll

我在 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 语句中的 block 永远不会触发 - 它没有正确打印 ID,我相信这意味着 stringbuilder 没有像 C 中的 wchar_t 那样正确填充。该值是 0,这意味着它永远不会输入指针给出的信息是正确的,对吧?我可以做什么来解决这个问题?非常感谢任何帮助。

应该注意的是,扫描代码工作正常 - 它会检测击键,甚至按预期将 x 替换为 y。

最佳答案

根据我自己的挖掘和大量试验和错误,以下是如何让它发挥作用:

{
[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.

关于c# - 将 C dll 和方法导入到 c# 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19896187/

相关文章:

c# - HttpWebRequest 非常慢!

c++ - 为什么 clang 输出对齐特定的东西

c - 当我尝试增加 char 的 ascii 值时,为什么会得到随机数?

objective-c - 打印指针地址和&符号地址之间的区别

c++ - move unique_ptr 后,指向 unique_ptr 内容的指针的内容是否有效?

c - 为什么作者在这个链表插入操作中要使用双指针呢?

c# - 将 google 凭据用于生产应用程序的最佳方式是什么?

c# - 将 x.y 转换为 a/b,其中 x.y = a/b c#

c# - 在Windows XP计算机上运行SlimDX C#应用程序时遇到的麻烦

c - Windows 结构初始化错误 C2099 : initializer is not a constant