roger911 Posted June 25, 2018 Share Posted June 25, 2018 Hey, I'm trying to write a simple DLL utilizing OpenCV for image template matching functionality. Here's the DLL code : Header : #ifndef _DLL_TUTORIAL_H_ #define _DLL_TUTORIAL_H_ // This is basically to tell compiler that we want to include this code only once(incase duplication occurs), you include it in .cpp file(which we will soon do) #include <iostream> // Inlcude basic c++ standard library output header(this is used for output text on the screen in our code) #if defined DLL_EXPORT #define DECLDIR __declspec(dllexport) #else #define DECLDIR __declspec(dllimport) #endif // We #define __declspec(dllexport) as DECLDIR macro so when compiler sees DECLDIR it will just take it as __declspec(dllexport)(say that DECLDIR is for readability) // Note that there is also __declspec(dllimport) for internal linking with others programs but since we just need to export our functions so we can use them with Autoit, thats all we need! extern "C" // this extern just wraps things up to make sure things work with C and not only C++ { // Here we declare our functions(as we do with normal functions in c header files, our cpp file will define them(later). Remember that DECLDIR is just a shortcut for __declspec(dllexport) DECLDIR int MatchingMethod(int iMatchMethod, void*, std::string SearchIn, std::string SearchFor); DECLDIR int add(int x, int y); } #endif // closing #ifndef _DLL_TUTORIAL_H_ Sources : expandcollapse popup// ITM.cpp : Defines the exported functions for the DLL application. // #include <Windows.h> #include "ITM.h" #include "stdafx.h" #include <iostream> #include <opencv2/opencv.hpp> #define DLL_EXPORT using namespace std; using namespace cv; extern "C" { int MatchingMethod(int iMatchMethod, void*, string SearchIn, string SearchFor) { return 999; cv::Mat ref = cv::imread(SearchIn); cv::Mat tpl = cv::imread(SearchFor); if (ref.empty() || tpl.empty()) return -10; cv::Mat gref, gtpl; cv::cvtColor(ref, gref, CV_BGR2GRAY); cv::cvtColor(tpl, gtpl, CV_BGR2GRAY); cv::Mat res(ref.rows - tpl.rows + 1, ref.cols - tpl.cols + 1, CV_32FC1); cv::matchTemplate(gref, gtpl, res, iMatchMethod); cv::threshold(res, res, 0.1, 1., CV_THRESH_TOZERO); while (true) { double minval, maxval, threshold = 0.6; cv::Point minloc, maxloc; cv::minMaxLoc(res, &minval, &maxval, &minloc, &maxloc); if (maxval >= threshold) { return 1; break; } else { return 0; break; } } ref.release(); tpl.release(); res.release(); return -20; } int add(int x, int y) { return x + y; } } // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.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; } LIBRARY ITM DESCRIPTION "Image Template Matching DLL" EXPORTS MatchingMethod @1 add @2 Calling it in the autoit code : ... $fooResult1 = 1 $fooResult1 = DllCall("../Dependancies/ITM.dll", "int:cdecl", "MatchingMethod", "int", 1, "void*", Null, "std::string", "../img/Test/pngsearch.png", "std::string", "../img/Test/lookfor1.bmp") ;$fooResult1 = DllCall("../Dependancies/ITM.dll", "int:cdecl", "add", "int", 2, "int", 3) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $cZoneCheck $foo = GUICtrlRead($cZone) MsgBox(0, "Notify", $fooResult1[0]) EndSwitch WEnd So I assigned fooResult1 to [1] to determine whether it was actually being assigned a value because calling the result in a msgbox without an array was resulting in 0 regardless, then I read up that if you call the result as an array, it would work. Did this with the add function and voila it worked! Then I tested the matchingmethod function and I get a : Line 180 (File "..\SCRIPTNAME.au3": MsgBox(0, "Notify", $fooResult1[0]) MsgBox(0, "Notify", #fooResult1^ ERROR Error : Subscript used on non-accessible variable. I'm wondering if this has anything to do with the includes in the DLL file? (Though I did link and include them properly I believe, added the include directory under C/C++ general, the lib directory in the linker general Additional Lib directories, and the .lib files under the Linker input additional lib files). Anyone know what's going on here? Link to comment Share on other sites More sharing options...
roger911 Posted June 25, 2018 Author Share Posted June 25, 2018 Welp, can't edit the previous post... So basically I removed all the code inside the function, and just had return 999; in it. Still giving the same error, which leads me to believe the issue lies in the variable usage in the required variables. I've tried removing the using x lines, swapping everything to use std:: or cv::, issue persists, tried swapping "std::string" with "string" in the variable type declaration in the DLL call, issue persists. replaced void with void*, etc etc. Still no progress... Are strings and void* not supported in DLL calls? Link to comment Share on other sites More sharing options...
TheXman Posted June 25, 2018 Share Posted June 25, 2018 48 minutes ago, roger911 said: Are strings and void* not supported in DLL calls? @roger911 When you looked at the help file for the DllCall function, in the list of "types" did you see "void" or "string" as a valid type? I didn't. I saw "none" for void and either "str" or "wstr" for strings. Maybe another thorough reading of the DllCall syntax is in order? https://www.autoitscript.com/autoit3/docs/functions/DllCall.htm roger911 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
roger911 Posted June 25, 2018 Author Share Posted June 25, 2018 Thanks Xman, this helped me somewhat. I fixed the Autoit code as per the reference, and when using flat words such as "foo" it seems to run fine, and returns -10 as no file was loaded. Then I input the pathing for "../img/Test/pngsearch.png" and ran it. Autoit Opened, waited for a second then closed with a return value of 0 as though it has completed it's task and has closed. After removing the special characters again it worked. I threw all the files in the same directory, and ran it again, then it ran and closed itself again. This is pretty frustrating. Link to comment Share on other sites More sharing options...
TheXman Posted June 25, 2018 Share Posted June 25, 2018 You're making progress and that's a good thing. Not being able to see your updated AutoIt code makes it almost impossible to see whether the issue is in your C function or the AutoIt call. If it is in your C code, that falls outside the scope of this forum but others may help you with that. If it is an AutoIt issue, I'm sure I can help you get past it. roger911 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
Danyfirex Posted June 25, 2018 Share Posted June 25, 2018 Hello. Debug your code. make sure you get a valid path check inside your dll maybe using a messagebox, also share you dllcall to be sure if you're doing well. Saludos roger911 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
roger911 Posted June 25, 2018 Author Share Posted June 25, 2018 ;$fooResult1 = DllCall("ITM.dll", "int", "MatchingMethod", "int", 1, "str", "pngsearch.png", "str", "lookfor.bmp") $fooResult1 = "notfoo" $fooResult1 = DllCall("ITM.dll", "str", "feedback", "str", "foo") While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $cZoneCheck $foo = GUICtrlRead($cZone) MsgBox(0, "Notify", $fooResult1[0]) EndSwit Well, I decided to run everything in the same folder. The function is working but the portion in C/C++ was returning as though the files weren't loaded even though they were given proper filenames. To verify that the issue wasn't in C/C++ I decided to make a makeshift function which would accept a string then feed it back. std::string feedback(std::string foo) { return foo; } The program runs fine, and $fooResult1 is being assigned post "notfoo" assignment, however, on the message box, array 1-3, or no array. All turns up empty. This is leading me to believe that the string variables aren't being passed through to the DLL properly. Link to comment Share on other sites More sharing options...
Danyfirex Posted June 25, 2018 Share Posted June 25, 2018 (edited) Hello use const char * in your dll. also add cdecl in your dllcall return type value, check help file. Saludos Edited June 25, 2018 by Danyfirex Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
roger911 Posted June 25, 2018 Author Share Posted June 25, 2018 Done, done, and done. So, using OpenCV and image template matching, I've built a DLL which does an image search. This works! Attached is the DLL (You may require the dependancy files/installation of OpenCV which you can get from sourceforge - https://sourceforge.net/projects/opencvlibrary/) Source files for the DLL are in ITM.7z (ITM.h, ITM.cpp, ITM.def, stdafx.h, stdafx.cpp). If you want to compile it yourself, just make sure to install and link the openCV libs. TYVM Dany and Xman! ITM.dll ITM.7z Danyfirex 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now