Davide Visconti 5 Posted January 3, 2019 (edited) Hi, I've upgrade a library to the new version, we usually import this library as Type Library (COM object) in Delphi (since "yesterday"). Now, in this new version the COM object are no longer supported, so I'm looking around. The new library support the C# .NET, C++ (unmanaged), C++ (managed) and C. I know that I can use the C .dll with a Delphi wrapper but... Just out of curiosity I tried to import the .NET Assembly. I never use the .NET Assembly before, and honestly I don't know very well what is the .NET Assembly. I'm searching on google and I found some documentations, but before start reading I ask you if you know a good start point "Delphi and .NET Assembly". Do you have experience with that? After the import I get the wrapper with a lot of class/interface but they are all empty. Eg: // *********************************************************************// // Interface: _HObject // Flags: (4432) Hidden Dual OleAutomation Dispatchable // GUID: {8E90512D-E586-352A-A70F-C7F1518E667D} // *********************************************************************// _HObject = interface(IDispatch) ['{8E90512D-E586-352A-A70F-C7F1518E667D}'] end; // *********************************************************************// // Interface: _HImage // Flags: (4432) Hidden Dual OleAutomation Dispatchable // GUID: {2D195846-332C-32E4-A6A3-8B089435BB54} // *********************************************************************// _HImage = interface(IDispatch) ['{2D195846-332C-32E4-A6A3-8B089435BB54}'] end; Any suggestion will be appreciate. Thank you, as always, for your time. Edited January 3, 2019 by Davide Visconti Share this post Link to post
David Heffernan 2353 Posted January 3, 2019 Very hard to see anything useful coming from this. Can't imagine any way for Delphi to directly consume a managed assembly other than COM. I'd consider making your own COM wrapper of the assembly, using C#, or writing a Delphi wrapper around the C interface. Share this post Link to post
Davide Visconti 5 Posted January 3, 2019 3 hours ago, David Heffernan said: Very hard to see anything useful coming from this. Can't imagine any way for Delphi to directly consume a managed assembly other than COM. I'd consider making your own COM wrapper of the assembly, using C#, or writing a Delphi wrapper around the C interface. Thanks David, if I have to write a wrapper in C# to expose the COM.... I definitely prefer write a Delphi wrapper over C dll, that's what usually we do (.h --> .pas). Thank you anyway for the suggestion. Share this post Link to post
sh17 26 Posted January 7, 2019 you can check this https://github.com/3F/DllExport Share this post Link to post
David Heffernan 2353 Posted January 7, 2019 12 minutes ago, sh17 said: you can check this https://github.com/3F/DllExport Not much point creating an unmanaged wrapper when the library ships with one out of the box. Share this post Link to post
MatthiasPeters 1 Posted June 6, 2023 I know this thing is more than 4 years old but it is really interesting for me. It seems this is about using the Halcon image library by MVTec with Delphi. If anyone has a solution how to use the latest halcon version with Delphi please contact me. Thank you! Share this post Link to post
DelphiUdIT 187 Posted June 6, 2023 This is all that you need to work for the Halcon 22.11 Steady and Delphi. Hope this help you. Bye HalconC_2211.pas 2 Share this post Link to post
MatthiasPeters 1 Posted June 7, 2023 19 hours ago, DelphiUdIT said: This is all that you need to work for the Halcon 22.11 Steady and Delphi. Hope this help you. Bye HalconC_2211.pas Thank you very much for that quick reply on my call for help regarding using Halcon with Delphi. Are you using this method yourself? I see that it seems to be easy to use the calls to the Halcon C-library. The only thing I wonder about is how to create some output of images and regions? Or how about drawing regions? I am using Halcon 20.11 steady now, which is the last Halcon Version that had (inofficial) support for the COM interface and we had a component named HWinXCtrl for that. Share this post Link to post
DelphiUdIT 187 Posted June 7, 2023 (edited) 14 minutes ago, MatthiasPeters said: Thank you very much for that quick reply on my call for help regarding using Halcon with Delphi. Are you using this method yourself? I see that it seems to be easy to use the calls to the Halcon C-library. The only thing I wonder about is how to create some output of images and regions? Or how about drawing regions? I am using Halcon 20.11 steady now, which is the last Halcon Version that had (inofficial) support for the COM interface and we had a component named HWinXCtrl for that. I knew that Halcon informally supported COM up to version 18.05. After that, COM support was dropped entirely. I think that you can use COM with 20.11 only for the old functions. But that doesn't matter, since they decided to remove COM support anyway and therefore it was still necessary to switch to something else. Meanwhile, I'm attaching the wrapper for 20.11 Steady (which is the penultimate version), then I'm attaching an example for 20.11 to use the wrapper similarly to how you now use COM. I'll give you the example with a THREAD, which is the best way to use Halcon. HalconC_2011.pas Bye Edited June 7, 2023 by DelphiUdIT 1 1 Share this post Link to post
DelphiUdIT 187 Posted June 7, 2023 (edited) This is sample program ready for Halcon 20.11 Steady. https://cloud.dyn-o-saur.com/Project_H2011.zip Bye Edited June 7, 2023 by DelphiUdIT 1 Share this post Link to post
MatthiasPeters 1 Posted June 7, 2023 (edited) Wow, that is really impressive. Thank you so much for sharing this with me. I hope we can use this to upgrade our software to Halcon 22.11 steady. One more question: did you create the HalconC_2011.pas and HalconC_2211.pas fully automatically with this tool https://github.com/neslib/Chet or did you make some manual adjustments to the file? Btw: indeed the com interface for Halcon 20.11 was not made public officially but MVTec generously created a special version for us - however they said it would be the last one.... Edited June 7, 2023 by MatthiasPeters Share this post Link to post
DelphiUdIT 187 Posted June 7, 2023 9 minutes ago, MatthiasPeters said: Wow, that is really impressing. Thank you so much for sharing this with me. I hope we can use this to upgrade our software to Halcon 22.11 steady. One more question: did you create the HalconC_2011.pas and HalconC_2211.pas fully automatically with this tool https://github.com/neslib/Chet or did you make some manual adjustments to the file? I used that tool, but to use it i had modified the include file (.h) of Halcon and after that i had manually adjust the pas file results of Chet. Some manually works, every 3 years 1 Share this post Link to post
MatthiasPeters 1 Posted June 7, 2023 Have you created some bigger projects with this yet? No problem with memory leaks so far? A while ago I made an attempt with this tool: https://www.crystalnet-tech.com/RuntimeLibrary/RuntimeLibrary4Delphi to get the .net assembly working in Delphi. It worked somehow but there were big problems with memory holes. There have been some updates to that software in the meantime but I could not find the time yet to make another try. Share this post Link to post
DelphiUdIT 187 Posted June 7, 2023 (edited) This is not an interface with .net assembly. It's a wrapper around C library. This will use the HalconC.dll. Nothing to do with .Net. And Yes i created lot of projects, may be not very big but most of them use 20 and more thread like that in the examples (of course with more and more functions inside) with Halcon. I don't have memory leak, but you must care to "clear" every single hobject that you use, before use it (not need if you are sure that is nil). If you reuse an object without clear it and it's already in use you will "lost" the memory (means LEAKS). Also, the wrapper don't has any know about macro, so you cannot use Halcon macro in Delphi. But this was never a problem for me. Bye Edited June 7, 2023 by DelphiUdIT 1 Share this post Link to post
MatthiasPeters 1 Posted June 12, 2023 I know that my .net approach was a different thing. Still it is about the same goal: using the latest Halcon versions with Delphi. We were about to give up and start rewriting a very big software project in C# or C++ because we thought there would be no clean way to continue with Delphi. I'm so glad you proved me wrong. I hope I'll find the time in the next days to work with your sample projects a little. What I'd like to test is for example if the "draw" procedures (like " T_draw_rectangle1 " for example) work as well. We need those so that the user can define a ROI (Region Of Interest). You wrote: <quote> I used that tool, but to use it i had modified the include file (.h) of Halcon and after that i had manually adjust the pas file results of Chet. </quote> can you tell me more about what kind of adjustements were necessary in the created pas file? Thanks! Share this post Link to post
DelphiUdIT 187 Posted June 12, 2023 (edited) It's a bit complex to explain, however I try. First, to use CHET you have to put all the includes you need into one directory, and then you have to change the definition in the individual file references, which originally point to subdirectories. Second, unlike C, where you can declare variables or definitions anywhere and even out of order, in the wrapper, declarations must be "ordered" (ie first you declare something, then you use it). So you have to take the generated .pas and move several declaration blocks at the head of the wrapper (or between various other declarations). It's not very complex, it just takes a little patience and taking into account that I do it every three years or so, everything is manageable. Another good thing is that once you've done it, you can use tools like Beyond Compare to help you: between the various versions of Halcon there are no abysmal differences, so much so that normally you just need to recompile the projects (or at least change some variables) to port to the new version. In updates between versions (for example between 20.11.01 and 20.11.03) there are no changes in the includes (unless it is explicitly highlighted in the notes) and therefore there is no need to change the wrapper. I normally use the Draw_Rectangle and similar functions without problems. If you want advice, when you can use the functions without the T_ as they use normal variables and not tuples. var ro1, co1, ro2, co2: double; //SomeWhere should be decalre "fWindowHandle: HLong;" and should be assigned of course Draw_Rectangle1(fWindowHandle, @ro1, @co1, @ro2, @co2); //and you can use of course also the _mod function ..... Bye P.S.: Beware of one "thing": when a function returns multiple elements (for example a list of points), it MUST be used in the form "T_" i.e. with tuples, unless it is certain that only one value is returned, such as example when preceded by the SelectObj function. Edited June 12, 2023 by DelphiUdIT 1 Share this post Link to post
BorisRurenko 0 Posted June 12, 2023 Hi all, I'm also interested in the Halcon connection in Delphi. I want to try to convert all Halcon libraries with CHET. Now many other standard libraries are used. Like windows.h and stdint.h... You've probably already made this adjustment. Can you upload your directory "C:\Programs\MVTec\HALCON-20.11-Steady\include" or 22.11 to compare with the original? Share this post Link to post
DelphiUdIT 187 Posted June 12, 2023 (edited) 28 minutes ago, BorisRurenko said: Hi all, I'm also interested in the Halcon connection in Delphi. I want to try to convert all Halcon libraries with CHET. Now many other standard libraries are used. Like windows.h and stdint.h... You've probably already made this adjustment. Can you upload your directory "C:\Programs\MVTec\HALCON-20.11-Steady\include" or 22.11 to compare with the original? ..................... Hello, with CHET you don't have do include nothing. It works on LLVM and this should be available in your system. A community edition of Visual Studio is typically necessary for this. Read the instructions for CHET. I cannot share the include file, 'cause they are not redistributable, but like i told in previous post you have to copy the .h files of halcon in one directory and go on. Some errors will be exposed because some files exposed a subdir path, change this and all will be done. Again, some functions refer to a wrong dll and you must change this in the wrapper (.pas file), but in my previous attachment you can see that. PS.: all Halcon libraries are converted in the wrappers that I posted. But in the wrapper that are only declarations, no code inside of course. Bye Edited June 12, 2023 by DelphiUdIT 1 Share this post Link to post
DelphiUdIT 187 Posted November 21 On 6/12/2023 at 9:16 AM, MatthiasPeters said: can you tell me more about what kind of adjustements were necessary in the created pas file? I update this topic 'cause new versions are released of Halcon (and quote Matthias that were interested about that). I post a Delphi wrapper around this, not a really Delphi wrapper, only a porting from C headers that I have done with CHET. Take care that some adjustments should be done from your previous sources because in Halcon are changed some records (Tuples), and for other reasons too. Read carefully the "Release Notes for HALCON 24.11.1.0 Progress-Steady" (https://www.mvtec.com/products/halcon/work-with-halcon/documentation/release-notes-2411-1) for full details. I tried the new wrapper only partially. Bye HalconC_2411.pas 1 Share this post Link to post
MatthiasPeters 1 Posted December 6 Thank you so much for providing this Update for the latest Halcon Version 24.11! In the meantime, I started writing a wrapper class that allows me to keep my old Halcon Com-Interface based code more or less as it is and internally call the C-functions. Example: procedure THalconOperators.DoOcrSingleClassMlp(CharacterRegion, CharacterImage: HObject; OCRHandle, OleNum: OleVariant; var OleClass, OleConfidence: OleVariant); var TupHandle: HTuple; TupNum: HTuple; TupClass: HTuple; TupConfidence: HTuple; begin OleVariant2HTuple(OCRHandle, @TupHandle, True); OleVariant2HTuple(OleNum, @TupNum); T_do_ocr_single_class_mlp(CharacterRegion, CharacterImage, TupHandle, TupNum, @TupClass, @TupConfidence); OleClass := HTuple2OleVariant(TupClass); OleConfidence := HTuple2OleVariant(TupConfidence); F_destroy_tuple(@TupHandle); F_destroy_tuple(@TupNum); F_destroy_tuple(@TupClass); F_destroy_tuple(@TupConfidence); end; So the idea is: convert all "OleVariant" varibales into "HTuple" (with my self-written procedure "OleVariant2HTuple") , call the C-function and convert the returned tuples into "OleVariant" variables again (with my function "HTuple2OleVariant"). With this it was relatively simple to convert an entire project from using the COM interface to using the C-library. Now I tried to compile my project with the latest "Halcon2411.pas" that you provided and I runt into a problem: the structure of the record "HTuple" (aka "HCTuple") has changed and is now: Hctuple = record val: Hcpar; num: INT4_8; capacity: INT4_8; flags: Integer; elem: Hcelem; end; before it was HTUPLE = record val: Hpar; &type: HINT; pad: array [0..3] of UTF8Char; num: INT4_8; capacity: INT4_8; free: HINT; elem: Hcelem; end; so we don't have the field "&type" any more? Why is that? I find it so confusing that all of a sudden one of the most important structures of this library (the TUPLE) is changed. Another issue that I have is that I didn't manage to use the "CHET" programme for creating the *.PAS File out of the halcon *.h files like you did it. It would be really helpful if you could provide me with more detailed info on what *.h files you copied into one directory and what changes you needed to do to them to successfully create a *.pas file out of this. In any case I am really greatful for the fantastic job that you did, showing that it is possible to use even the latest HALCON versions with Delphi. 1 Share this post Link to post
DelphiUdIT 187 Posted December 6 (edited) 10 hours ago, MatthiasPeters said: With this it was relatively simple to convert an entire project from using the COM interface to using the C-library. Now I tried to compile my project with the latest "Halcon2411.pas" that you provided and I runt into a problem: the structure of the record "HTuple" (aka "HCTuple") has changed and is now: Hctuple = record val: Hcpar; num: INT4_8; capacity: INT4_8; flags: Integer; elem: Hcelem; end; before it was HTUPLE = record val: Hpar; &type: HINT; pad: array [0..3] of UTF8Char; num: INT4_8; capacity: INT4_8; free: HINT; elem: Hcelem; end; so we don't have the field "&type" any more? Why is that? I find it so confusing that all of a sudden one of the most important structures of this library (the TUPLE) is changed. The structure was changed and reported to the release notes: Quote The HTuple::GetHctuple() member function has been changed to take a reference to an Hctuple structure to copy the data to instead of returning an Hctuple. The undocumented at_i, at_d, at_h, and at_s macros have been removed from HalconCDefs.h. The signature of the HGetPPar function has changed so that the third parameter now takes a Hcpar const* H_RESTRICT* parameter instead of a Hcpar* H_RESTRICT* parameter. Any code calling HGetPPar directly or indirectly will need to be changed. Note that this is not a semantic change, as the documentation for HGetPPar states that the Hcpar values returned by HGetPPar must not be modified. This change makes this restriction explicit to the compiler. The new field "val" is an Hcpar type. It contains the old "HPar" members ("par" pointer) and "&type". So, while before it was possible to access the value of the Tuple directly, now it is accessed via "par": var fDeviceHandle: HTuple; ----- //New way if fDeviceHandle.val.par.l <> 0 then ..... //Old way if fDeviceHandle.val.l <> 0 then Other important thing is that the float field "f" doesn't exist anymore .... (I dont' know any official notes about that). This should not have a major impact on the code, since "f" is a further definition of an identically field type "d", so replacing "f" with "d" in the code will make both the old and new code compile without errors and without any {$IFDEF... This is the first time in many years that they have changed the interface to a basic structure like HTuple making the code totally incompatible with the past. In the past they had changed some definition of some parameters, but by changing only the declaration of the variable everything was back to normal without any change in the "procedural" code (I remember something about the parameters of the "get_mposition" function for example). 10 hours ago, MatthiasPeters said: Another issue that I have is that I didn't manage to use the "CHET" programme for creating the *.PAS File out of the halcon *.h files like you did it. It would be really helpful if you could provide me with more detailed info on what *.h files you copied into one directory and what changes you needed to do to them to successfully create a *.pas file out of this. What I did: 1) Copy all include files (except Halcon.h) in a single directory wherever you want; 2) Run CHET (this is my example): You will see some errors about include files not found ... change the relative path in the source originated the error. Retry the RUN, and go redoing the same until all errors are gone. After that you have the PAS file. Now You have to change (in reality move at the top of file) some declarations, for obviuos reasons that you will see ... is more complicated to explain that to do. Some change to definitions (like NULL), and you should also modifiy some declarations that point to wrong DLL, refer to my original wrapper searching for "LIB_MVTEC_SYSTEM". Without this you will have a runtime error in the application if you use some system functions. A little bit too: you must delete (or divide) some very long commented lines: That's all. Edited December 6 by DelphiUdIT 1 Share this post Link to post