Whenever I try to reference my own DLL in C# through Visual Studio, it tells me it was unable to make a reference to the DLL as it's not a COM library.
I've searched around the internet to find a solution to this with no clear answer or help any where really. It's a rather "simple" DLL which captures the raw picture data from a Fingerprint Scanner. I have tested that the C++ code worked just fine before I tried to make it into a DLL, just so you know.
I followed Microsofts guide on how to make a DLL and here is what I ended up with:
- JTBioCaptureFuncsDll.h
- JTBioCaptureFuncsDll.cpp
- JTBioCapture.cpp
JTBioCaptureFuncsDll.h
#ifdef JTBIOCAPTUREFUNCSDLL_EXPORTS #define JTBIOCAPTUREFUNCSDLL_API __declspec(dllexport) #else #define JTBIOCAPTUREFUNCSDLL_API __declspec(dllimport) #endif using byte = unsigned char*; struct BioCaptureSample { INT32 Width; INT32 Height; INT32 PixelDepth; byte Buffer; }; JTBioCaptureFuncsDll.cpp
// JTBioCapture.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" namespace JTBioCapture { using byte = unsigned char*; class JTBioCapture { public: // Returns a Struct with Information Regarding the Fingerprint Sample static JTBIOCAPTUREFUNCSDLL_API BioCaptureSample CaptureSample(); }; } JTBioCapture.cpp
/* * Courtesy of WinBio God Satish Agrawal on Stackoverflow */ BioCaptureSample CaptureSample() { HRESULT hr = S_OK; WINBIO_SESSION_HANDLE sessionHandle = NULL; WINBIO_UNIT_ID unitId = 0; WINBIO_REJECT_DETAIL rejectDetail = 0; PWINBIO_BIR sample = NULL; SIZE_T sampleSize = 0; // Connect to the system pool. hr = WinBioOpenSession( WINBIO_TYPE_FINGERPRINT, // Service provider WINBIO_POOL_SYSTEM, // Pool type WINBIO_FLAG_RAW, // Access: Capture raw data NULL, // Array of biometric unit IDs 0, // Count of biometric unit IDs WINBIO_DB_DEFAULT, // Default database &sessionHandle // [out] Session handle ); if (FAILED(hr)) { wprintf_s(L"\n WinBioOpenSession failed. hr = 0x%x\n", hr); goto e_Exit; } // Capture a biometric sample. wprintf_s(L"\n Calling WinBioCaptureSample - Swipe sensor...\n"); hr = WinBioCaptureSample( sessionHandle, WINBIO_NO_PURPOSE_AVAILABLE, WINBIO_DATA_FLAG_RAW, &unitId, &sample, &sampleSize, &rejectDetail ); if (FAILED(hr)) { if (hr == WINBIO_E_BAD_CAPTURE) { wprintf_s(L"\n Bad capture; reason: %d\n", rejectDetail); } else { wprintf_s(L"\n WinBioCaptureSample failed. hr = 0x%x\n", hr); } goto e_Exit; } wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId); wprintf_s(L"\n Captured %d bytes.\n", sampleSize); // Courtesy of Art "Messiah" Baker at Microsoft PWINBIO_BIR_HEADER BirHeader = (PWINBIO_BIR_HEADER)(((PBYTE)sample) + sample->HeaderBlock.Offset); PWINBIO_BDB_ANSI_381_HEADER AnsiBdbHeader = (PWINBIO_BDB_ANSI_381_HEADER)(((PBYTE)sample) + sample->StandardDataBlock.Offset); PWINBIO_BDB_ANSI_381_RECORD AnsiBdbRecord = (PWINBIO_BDB_ANSI_381_RECORD)(((PBYTE)AnsiBdbHeader) + sizeof(WINBIO_BDB_ANSI_381_HEADER)); PBYTE firstPixel = (PBYTE)((PBYTE)AnsiBdbRecord) + sizeof(WINBIO_BDB_ANSI_381_RECORD); int width = AnsiBdbRecord->HorizontalLineLength; int height = AnsiBdbRecord->VerticalLineLength; wprintf_s(L"\n ID: %d\n", AnsiBdbHeader->ProductId.Owner); wprintf_s(L"\n Width: %d\n", AnsiBdbRecord->HorizontalLineLength); wprintf_s(L"\n Height: %d\n", AnsiBdbRecord->VerticalLineLength); BioCaptureSample returnSample; byte byteBuffer; for (int i = 0; i < AnsiBdbRecord->BlockLength; i++) { byteBuffer[i] = firstPixel[i]; } returnSample.Buffer = byteBuffer; returnSample.Height = height; returnSample.Width = width; returnSample.PixelDepth = AnsiBdbHeader->PixelDepth; /* * NOTE: (width / 3) is necessary because we ask for a 24-bit BMP but is only provided * a greyscale image which is 8-bit. So we have to cut the bytes by a factor of 3. */ // Commented out as we only need the Byte buffer. Comment it back in should you need to save a BMP of the fingerprint. // bool b = SaveBMP(firstPixel, (width / 3), height, AnsiBdbRecord->BlockLength, L"C:\\Users\\smf\\Desktop\\fingerprint.bmp"); // wprintf_s(L"\n Success: %d\n", b); e_Exit: if (sample != NULL) { WinBioFree(sample); sample = NULL; } if (sessionHandle != NULL) { WinBioCloseSession(sessionHandle); sessionHandle = NULL; } wprintf_s(L"\n Press any key to exit..."); _getch(); return returnSample; } The idea is that in C# you call "CaptureSample()" and then the code attempts to capture a fingerprint scan. When it does a scan, a struct should be returned to C# that it can work with, holding:
- Byte Buffer
- Image Height
- Image Width
- Image Pixeldepth
But when I try to reference the DLL in my C# project I get the following error:
I have also tried to use the TlbImp.exe tool to make the DLL but to no avail. It tells me that the DLL is not a valid type library.
So I'm a bit lost here. I'm new to C++ so making an Interop/COM Component is not something I've done before nor make a DLL for use in C#.
