Open takuya-takeuchi opened 6 years ago
After turned on Enable native code debugging, IDE show the following dialog
In unmanaged application, despite Win32 sample is x86 or x64, it works fine.
C++/CLI console apps also works fine.
#include "stdafx.h"
using namespace System;
void CALLBACK WINBIO_ASYNC_COMPLETION_CALLBACK(PWINBIO_ASYNC_RESULT AsyncResult)
{
}
int main(array<System::String ^> ^args)
{
WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod = WINBIO_ASYNC_NOTIFY_CALLBACK;
HWND TargetWindow = NULL;
UINT MessageCode = 0;
PVOID UserData = NULL;
BOOL AsynchronousOpen = TRUE;
WINBIO_FRAMEWORK_HANDLE FrameworkHandle;
HRESULT hr = WinBioAsyncOpenFramework(
NotificationMethod,
TargetWindow,
MessageCode,
WINBIO_ASYNC_COMPLETION_CALLBACK,
UserData,
AsynchronousOpen,
&FrameworkHandle
);
return 0;
}
Create C++/CLI library which call AsyncOpenFramework and C$ console app which call C++/CLI library, then it works fine.
#include "stdafx.h"
#include "ClassLibrary1.h"
namespace ClassLibrary1 {
void CALLBACK WINBIO_ASYNC_COMPLETION_CALLBACK(PWINBIO_ASYNC_RESULT AsyncResult)
{
}
HRESULT Class1::Test()
{
WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod = WINBIO_ASYNC_NOTIFY_CALLBACK;
HWND TargetWindow = NULL;
UINT MessageCode = 0;
PVOID UserData = NULL;
BOOL AsynchronousOpen = TRUE;
WINBIO_FRAMEWORK_HANDLE FrameworkHandle;
HRESULT hr = WinBioAsyncOpenFramework(
NotificationMethod,
TargetWindow,
MessageCode,
WINBIO_ASYNC_COMPLETION_CALLBACK,
UserData,
AsynchronousOpen,
&FrameworkHandle
);
return hr;
}
}
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var test = new ClassLibrary1.Class1();
var ret = test.Test();
Console.WriteLine(ret);
}
}
}
Minimum C# apps does not work.
using System;
using System.Runtime.InteropServices;
using BOOL = System.Int32;
using HRESULT = System.Int32;
using HWND = System.IntPtr;
using PVOID = System.IntPtr;
using UINT = System.UInt32;
using WINBIO_FRAMEWORK_HANDLE = System.UInt32;
namespace ConsoleApp2
{
class Program
{
private const string DllName = "Winbio.dll";
public enum WINBIO_ASYNC_NOTIFICATION_METHOD
{
WINBIO_ASYNC_NOTIFY_NONE = 0,
WINBIO_ASYNC_NOTIFY_CALLBACK,
WINBIO_ASYNC_NOTIFY_MESSAGE,
WINBIO_ASYNC_NOTIFY_MAXIMUM_VALUE
}
public delegate void WINBIO_ASYNC_COMPLETION_CALLBACK([In] IntPtr AsyncResult);
[DllImport(DllName)]
public static extern HRESULT WinBioAsyncOpenFramework([In] WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod,
[In] HWND TargetWindow,
[In] UINT MessageCode,
[In] WINBIO_ASYNC_COMPLETION_CALLBACK CallbackRoutine,
[In] PVOID UserData,
[In] BOOL AsynchronousOpen,
[Out] out WINBIO_FRAMEWORK_HANDLE FrameworkHandle);
private static void AsyncCompletedCallback(IntPtr asyncResult)
{
}
static void Main(string[] args)
{
var NotificationMethod = WINBIO_ASYNC_NOTIFICATION_METHOD.WINBIO_ASYNC_NOTIFY_CALLBACK;
IntPtr TargetWindow = IntPtr.Zero;
UINT MessageCode = 0;
PVOID UserData = IntPtr.Zero;
var AsynchronousOpen = 1;
var hr = WinBioAsyncOpenFramework(NotificationMethod,
TargetWindow,
0,
AsyncCompletedCallback,
UserData,
AsynchronousOpen,
out var h);
Console.WriteLine(hr);
}
}
}
Win32 with dynamic call looks like p/invoke by using LoadLibrary. It does not link any Windows Biometric Framework library. It works fine.
#include "stdafx.h"
#include "windows.h"
#include "WinBio.h"
typedef HRESULT(WINAPI *WINBIOASYNCOPENFRAMEWORK)
(
_In_ WINBIO_ASYNC_NOTIFICATION_METHOD,
_In_opt_ HWND,
_In_opt_ UINT,
_In_opt_ PWINBIO_ASYNC_COMPLETION_CALLBACK,
_In_opt_ PVOID,
_In_ BOOL,
_Out_opt_ WINBIO_FRAMEWORK_HANDLE *
);
void CALLBACK WINBIO_ASYNC_COMPLETION_CALLBACK(PWINBIO_ASYNC_RESULT AsyncResult)
{
}
int main()
{
HMODULE hModule = LoadLibrary(_T("WinBio.dll"));
WINBIOASYNCOPENFRAMEWORK pFunc = (WINBIOASYNCOPENFRAMEWORK)GetProcAddress(hModule, "WinBioAsyncOpenFramework");
WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod = WINBIO_ASYNC_NOTIFY_CALLBACK;
HWND TargetWindow = NULL;
UINT MessageCode = 0;
PVOID UserData = NULL;
BOOL AsynchronousOpen = TRUE;
WINBIO_FRAMEWORK_HANDLE FrameworkHandle;
HRESULT hr = pFunc(
NotificationMethod,
TargetWindow,
MessageCode,
WINBIO_ASYNC_COMPLETION_CALLBACK,
UserData,
AsynchronousOpen,
&FrameworkHandle
);
return 0;
}
C# + LoadLibrary. It does not work.
using System;
using System.Runtime.InteropServices;
using BOOL = System.Int32;
using HRESULT = System.Int32;
using HWND = System.IntPtr;
using PVOID = System.IntPtr;
using UINT = System.UInt32;
using WINBIO_FRAMEWORK_HANDLE = System.UInt32;
namespace ConsoleApp4
{
class Program
{
private const string DllName = "Winbio.dll";
public enum WINBIO_ASYNC_NOTIFICATION_METHOD
{
WINBIO_ASYNC_NOTIFY_NONE = 0,
WINBIO_ASYNC_NOTIFY_CALLBACK,
WINBIO_ASYNC_NOTIFY_MESSAGE,
WINBIO_ASYNC_NOTIFY_MAXIMUM_VALUE
}
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32", SetLastError = true)]
internal static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)]
internal static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
public delegate void WINBIO_ASYNC_COMPLETION_CALLBACK([In] IntPtr AsyncResult);
public delegate HRESULT WinBioAsyncOpenFramework([In] WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod,
[In] HWND TargetWindow,
[In] UINT MessageCode,
[In] WINBIO_ASYNC_COMPLETION_CALLBACK CallbackRoutine,
[In] PVOID UserData,
[In] BOOL AsynchronousOpen,
[Out] out WINBIO_FRAMEWORK_HANDLE FrameworkHandle);
private static void AsyncCompletedCallback(IntPtr asyncResult)
{
}
static void Main(string[] args)
{
IntPtr handle = LoadLibrary(DllName);
IntPtr funcPtr = GetProcAddress(handle, nameof(WinBioAsyncOpenFramework));
WinBioAsyncOpenFramework func = (WinBioAsyncOpenFramework)Marshal.GetDelegateForFunctionPointer(funcPtr, typeof(WinBioAsyncOpenFramework));
var NotificationMethod = WINBIO_ASYNC_NOTIFICATION_METHOD.WINBIO_ASYNC_NOTIFY_CALLBACK;
IntPtr TargetWindow = IntPtr.Zero;
UINT MessageCode = 0;
PVOID UserData = IntPtr.Zero;
var AsynchronousOpen = 1;
var hr = func(NotificationMethod,
TargetWindow,
0,
AsyncCompletedCallback,
UserData,
AsynchronousOpen,
out var h);
Console.WriteLine(hr);
}
}
}
C++/CLI and C#, but pass the delegate pointer defined in managed to C++/CLI side. It does not work
#include "stdafx.h"
#include "ClassLibrary1.h"
namespace ClassLibrary1 {
void CALLBACK WINBIO_ASYNC_COMPLETION_CALLBACK(PWINBIO_ASYNC_RESULT AsyncResult)
{
}
HRESULT Class1::Test()
{
WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod = WINBIO_ASYNC_NOTIFY_CALLBACK;
HWND TargetWindow = NULL;
UINT MessageCode = 0;
PVOID UserData = NULL;
BOOL AsynchronousOpen = TRUE;
WINBIO_FRAMEWORK_HANDLE FrameworkHandle;
HRESULT hr = WinBioAsyncOpenFramework(
NotificationMethod,
TargetWindow,
MessageCode,
WINBIO_ASYNC_COMPLETION_CALLBACK,
UserData,
AsynchronousOpen,
&FrameworkHandle
);
return hr;
}
HRESULT Class1::Test2(void* func)
{
WINBIO_ASYNC_NOTIFICATION_METHOD NotificationMethod = WINBIO_ASYNC_NOTIFY_CALLBACK;
HWND TargetWindow = NULL;
UINT MessageCode = 0;
PVOID UserData = NULL;
BOOL AsynchronousOpen = TRUE;
WINBIO_FRAMEWORK_HANDLE FrameworkHandle;
HRESULT hr = WinBioAsyncOpenFramework(
NotificationMethod,
TargetWindow,
MessageCode,
(PWINBIO_ASYNC_COMPLETION_CALLBACK)func,
UserData,
AsynchronousOpen,
&FrameworkHandle
);
return hr;
}
}
using System;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
class Program
{
public delegate void WINBIO_ASYNC_COMPLETION_CALLBACK([In] IntPtr AsyncResult);
private static void AsyncCompletedCallback(IntPtr asyncResult)
{
}
static unsafe void Main(string[] args)
{
var test = new ClassLibrary1.Class1();
var ret = test.Test();
Console.WriteLine(ret);
var ptr = Marshal.GetFunctionPointerForDelegate<WINBIO_ASYNC_COMPLETION_CALLBACK>(AsyncCompletedCallback);
ret = test.Test2((void*)ptr);
Console.WriteLine(ret);
}
}
}
App Constitution | Result |
---|---|
Win32 | OK |
Win32 (by LoadLibrary) | OK |
C++/CLI app | OK |
C++/CLI (defined here) +C# app (.NET Framework) | OK |
C++/CLI (defined here) +C# app (.NET Framework, pass the delegate pointer) | NG |
C# app (.NET Framework) | NG |
C# app (by LoadLibrary) (.NET Framework) | NG |
C# app (.NET Core) | NG |
So
Just after call AsyncOpenFramework method with WINBIO_ASYNC_NOTIFY_CALLBACK, library throw exception with E_OUTOFMEMORY