简体   繁体   中英

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

Currently I'm trying to use a C++ library under C# using DLL importation. Library is called Interception. The problem is that I don't know how to translate #define entries and typedef declaration of the header file:

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

I tried to use "using" directive, but with no success (I can't access to the void definition). Moreover, I didn't understood the role of __declspec(dllimport) in this header. In my c# project, I just ignored it? Is it good to do that?

This is the code I want to use in c# (it's a sample of the library)

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

EDIT:

What I've tried: basic importation:

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

I don't know ho to convert InterceptionPredicate. According the header file, InterceptionFilter is a ushort, and InterceptionContext is a void pointer (void*).

The C++ library should be compiled as a .DLL file. This .DLL file should have exported functions. You can use the Depends tool to check what's exported from a .DLL. .NET code can call C++ exported functions using what's called "Platform Invoke".

Now, I strongly suggest you take a deep look at this Platform Invoke Tutorial that will guide you.

PS: void * should be declared in c# as IntPtr. enums should be redeclared as enums. Functions should be declared as static extern methods marked with the DllImport attribute.

First, it looks like you're trying to implement a global keyboard/mouse hook .. if that's the case, I'd recommend googling 'C# low level keyboard and mouse hook'.

Now for your question, first is the __declspec(dllimport) issue: this would be if you were actually using the header in a C++ application, that is the C++ equivilent of the C# DllImport .. so in effect you didn't ignore it, you implemented it. In C++ it just tells the linker that the function declared as such will be imported from a specific DLL instead of it being a local function (pretty similar to what the C# DllImport directive does)

Next is for function pointer issue (InterceptionPredicate). In the header it is defined as such:

typedef int (*InterceptionPredicate)(InterceptionDevice device);

And InterceptionDevice is just an 'int'. So the InterceptionPredicate is just a function pointer type (or Delegate in C#), so your delegate definition for InterceptionPredicate would look like this:

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

A note about the UnmanagedFunctionPointer calling convention descriptor: IF you know what kind of calling convention (stdcall, fastcall, cdecl) the exported function might be using, you could specify here so that the .NET marshaler will know how to pass the data between the managed/unmanaged code, but if you don't know it or it's not specified typically you can just leave that off.

Also, as others have mentioned, unless you have the 'unsafe' flag specified in your C# properties, a void* type should always be an IntPtr in C#.

Also, be sure to mark the dll function in your C# code as public static extern , see example below.

So to make an example of the function you've specified, here's what could be done:

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
        }
    }
}

Hope that gets you on the right track.

Ok, I found an example code that was hidden on the GIT. Thank you google!

https://gist.github.com/1959219

It precises all function from DLL importation, with a working example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM