usnistgov / NFIQ2

Optical live-scan and ink fingerprint image quality assessment tool
https://www.nist.gov/services-resources/software/development-nfiq-20
Other
130 stars 57 forks source link

Build issue when using build generated NFIQ2.lib in order to write wrapper. #381

Closed ammysh closed 6 months ago

ammysh commented 7 months ago

Describe the issue I have written a wrapper class in order to use NFIQ2.lib which will be further used in c# application to get quality score of finger image. I am having issue related to configuration while going to build wrapper project although I have defined inclulde and lib paths in the configuration of Wrapper class.

To reproduce Steps to reproduce the issue:

  1. Run cmake .. -DBUILD_NFIQ2_CLI=OFF after cloning the master branch.
  2. After that inside the build folder open NFIQ2_SUPERBUILD.sln which has been created after running above command.
  3. Then build nfiq2 project in order to create nfiq2.lib.
  4. When I used this lib file in my wrapper which includes following code and files it is producing errors. **Error LNK2038 mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease' in dllmain.obj NFIQ2Wrapper

Error LNK2005 "public: __cdecl std::_Lockit::_Lockit(int)" (??0_Lockit@std@@QEAA@H@Z) already defined in msvcprt.lib(MSVCP140.dll) NFIQ2Wrapper

Error LNK2005 "void __cdecl std::_Facet_Register(class std::_Facet_base *)" (?_Facet_Register@std@@YAXPEAV_Facet_base@1@@Z) already defined in msvcprt.lib(locale0_implib.obj) NFIQ2Wrapper D:\F drive\Work\NFIQ2\build\NFIQ2Wrapper\libcpmt.lib(locale0.obj) 1**

Expected behavior It should build without any issue related to configuration.

OS information

Library information

NFIQ 2 version information Hint: run nfiq2 and copy the entire block of text under Version Info

Code sample Is there a reliable code sample you can include?


// NFIQ2Wrapper.h
#pragma once

#include <string>
#include <vector>
#include <unordered_map>

namespace NFIQ2 {
    class Algorithm;
}

using namespace System;
using namespace System::Collections::Generic;

namespace NFIQ2Wrapper {
    public ref class NFIQ2ManagedWrapper
    {
    public:
        NFIQ2ManagedWrapper();
        ~NFIQ2ManagedWrapper();

        unsigned int ComputeQualityScore(array<System::Byte>^ imageData, int width, int height);
        unsigned int ComputeQualityScore(Dictionary<String^, double>^ features);

    private:
        NFIQ2::Algorithm* algorithmInstance;
    };
}

// NFIQ2Wrapper.cpp
#include "pch.h"
#include "NFIQ2Wrapper.h"
#include "nfiq2.hpp"
#include <msclr/marshal_cppstd.h>
#include <opencv2/opencv.hpp> // Include OpenCV header

using namespace NFIQ2;

namespace NFIQ2Wrapper {
    NFIQ2ManagedWrapper::NFIQ2ManagedWrapper()
    {
        algorithmInstance = new Algorithm();
    }

    NFIQ2ManagedWrapper::~NFIQ2ManagedWrapper()
    {
        delete algorithmInstance;
    }

    unsigned int NFIQ2ManagedWrapper::ComputeQualityScore(array<System::Byte>^ imageData, int width, int height)
    {

        pin_ptr<System::Byte> pinnedImageData = &imageData[0];
        uint8_t* nativeImageData = pinnedImageData;

        cv::Mat image(height, width, CV_8UC1, nativeImageData);

        if (image.empty()) {
            // Handle error loading image
            return 0; 
        }

        // Convert OpenCV Mat to NFIQ2 FingerprintImageData
        NFIQ2::FingerprintImageData rawImage(image.data, width * height, width, height, 0, 500); // Assuming fingerCode is 0 and ppi is 500

        // Compute quality score using NFIQ2::Algorithm
        NFIQ2::Algorithm algorithmInstance;
        return algorithmInstance.computeQualityScore(rawImage);
    }

    unsigned int NFIQ2ManagedWrapper::ComputeQualityScore(Dictionary<String^, double>^ features)
    {
        std::unordered_map<std::string, double> nativeFeatures;
        for each (KeyValuePair<String^, double> kvp in features)
        {
            std::string key = msclr::interop::marshal_as<std::string>(kvp.Key);
            nativeFeatures[key] = kvp.Value;
        }
        return algorithmInstance->computeQualityScore(nativeFeatures);
    }
}

// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.

#ifndef PCH_H
#define PCH_H

// add headers that you want to pre-compile here
#include "framework.h"

#endif //PCH_H
// pch.cpp: source file corresponding to the pre-compiled header

#include "pch.h"

// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "NFIQ2Wrapper.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Above are the code related to Wrapper class.
Add any other context about the problem here.
gfiumara commented 7 months ago

Error LNK2038 is related to the Debug release not being supported in master at this time. Please build your code as Release, or check out the branch from #364 and see if that fixes it for you. It looks like we never ran our compliance check on that PR so it was never merged unfortunately. I hope to get on that soon.

gfiumara commented 6 months ago

364 was merged and I haven't heard an update on this issue for 2 weeks, so closing with the expectation that #364 fixed your issue. Please re-open with more details if this is not the case.