まず、グローバルキーボード/マウスフックを実装しようとしているようです。その場合は、「C#低レベルキーボードとマウスフック」をグーグルで検索することをお勧めします。
さて、あなたの質問ですが、最初は__declspec(dllimport)
問題です。これは、実際にC ++アプリケーションでヘッダーを使用している場合、つまりC#と同等のC ++であるDllImport
場合です。したがって、実際にはそれを無視せずに実装しました。C ++では、そのように宣言された関数がローカル関数ではなく特定のDLLからインポートされることをリンカに通知するだけです(C#DllImport
ディレクティブの機能と非常によく似ています) 。
次は関数ポインタの問題(InterceptionPredicate)です。ヘッダーでは、次のように定義されています。
typedef int (*InterceptionPredicate)(InterceptionDevice device);
そして、それInterceptionDevice
は単なる「int」です。したがって、InterceptionPredicateは単なる関数ポインター型(またはC#のデリゲート)であるため、InterceptionPredicateのデリゲート定義は次のようになります。
// [UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate int InterceptionPredicate (int device);
UnmanagedFunctionPointer呼び出し規約記述子に関する注意:エクスポートされた関数が使用している可能性のある呼び出し規約(stdcall、fastcall、cdecl)の種類がわかっている場合は、ここで指定して、.NETマーシャラーがデータをマネージド/アンマネージドコードですが、それがわからない場合や通常は指定されていない場合は、そのままにしておくことができます。
また、他の人が言及しているように、C#プロパティで「unsafe」フラグが指定されていない限り、void*
型は常にIntPtr
C#である必要があります。
また、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
}
}
}
それがあなたを正しい軌道に乗せることを願っています。