导入:在C#下使用C 库的语法翻译

Importation: Syntax translation for using C++ library under C#

本文关键字:语法 翻译 导入      更新时间:2023-10-16

当前我正在尝试使用dll导入使用C#下的C 库。库称为拦截。问题是我不知道如何翻译#Define条目和标题文件的Typedef声明:

https://github.com/oblitum/interception/blob/master/include/interception.h

我尝试使用"使用"指令,但没有成功(我无法访问void定义)。此外,我不了解__declspec(dllimport)在此标题中的作用。在我的C#项目中,我只是忽略了它吗?这样做很好吗?

这是我想在C#中使用的代码(这是库的示例)

https://github.com/oblitum/interception/blob/master/samples/hardwareid/main.cpp

编辑:

我尝试了什么:基本导入:

[DllImport("interception.dll", CharSet = CharSet.Auto, SetLastError = true)]
    void interception_set_filter(void* context, InterceptionPredicate predicate, ushort filter);

我不知道Ho转换拦截场所。根据标题文件,拦截窗是一个吸管,interceptionContext是一个无效的指针(void*)。

C 库应编译为.dll文件。此.dll文件应具有导出的函数。您可以使用依赖工具检查.dll导出的内容。.NET代码可以使用所谓的"平台Indoke"调用C 导出的功能。

现在,我强烈建议您深入了解这个平台调用教程,以指导您。

ps:void *应在C#中声明为INTPTR。enums应重新定义为枚举。函数应声明为标记为DllImport属性的静态外部方法。

首先,看来您正在尝试实现全局键盘/鼠标钩。

现在就您的问题而言,首先是__declspec(dllimport)问题:这将是您实际上在C 应用程序中使用标头,即C 等效于C#DllImport ..因此,实际上您并没有忽略它,您实现了它。在C 中,它只是告诉链接器,该函数将从特定的dll导入而不是本地函数(与C#DllImport指令所做的相当相似)

接下来是用于函数指针问题(截距predicate)。在标题中,它被定义为:

typedef int (*InterceptionPredicate)(InterceptionDevice device);

InterceptionDevice只是一个" int"。因此,拦截式披露只是函数指针类型(或在C#中的委托),因此您的InterceptionPredicate的委托定义看起来像这样:

// [UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate int InterceptionPredicate (int device);

关于非管理FunctionPointer呼叫约定描述符的注释:如果您知道可能使用导出的函数的呼叫惯例(stdcall,fastcall,cdecl),则可以在此处指定。托管/非托管代码之间的数据,但是如果您不知道或未指定它,则可以将其删除。

另外,正如其他人所提到的,除非您在C#属性中指定了"不安全"标志,否则void*类型应始终是C#中的IntPtr

另外,请确保将C#代码中的DLL功能标记为public static extern,请参见下面的示例。

因此,为您指定的函数示例,这是可以做的:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace InterceptorTest
{
    public class Interceptor : IDisposable
    {
        #region DllImports
        [DllImport("interception.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr interception_create_context();
        [DllImport("interception.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern void interception_destroy_context(IntPtr context);
        [DllImport("interception.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern void interception_set_filter(IntPtr context, InterceptionPredicate predicate, ushort filter);
        // The function pointer type as defined in interception.h that needs to be defined as a delegate here
        public delegate int InterceptionPredicate(int device);
        #endregion
        #region private members
        private InterceptionPredicate m_PredicateDelegate { get; set; }
        private IntPtr m_Context { get; set; }
        #endregion
        #region methods
        public Interceptor(ushort filter)
        {
            // be sure to initialize the context
            this.m_PredicateDelegate = new InterceptionPredicate(this.DoSomethingWithInterceptionPredicate);
            this.m_Context = interception_create_context();
            interception_set_filter(this.m_Context, this.m_PredicateDelegate, filter);
        }
        private void Cleanup()
        {
            interception_destroy_context(this.m_Context);
            // the next line is not really needed but since we are dealing with
            // managed to unmanaged code it's typically best to set to 0
            this.m_Context = IntPtr.Zero;
        }
        public void Dispose()
        {
            this.Cleanup();
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (disposing) { this.Cleanup(); }
        }
        public int DoSomethingWithInterceptionPredicate(int device)
        {
            // this function is something you would define that would do something with
            // the device code (or whatever other paramaters your 'DllImport' function might have
            // and return whatever interception_set_filter is expecting
            return device;
        }
        #endregion
    }
    static class Program
    {
        [STAThread]
        private static void Main(string[] argv)
        {
            Interceptor icp = new Interceptor(10);
            // do something with the Interceptor object
        }
    }
}

希望您能使您走上正确的轨道。

好吧,我找到了一个隐藏在git上的示例代码。谢谢Google!

https://gist.github.com/1959219

它可以从DLL导入中精确所有功能,并使用一个工作示例。