Jump to content

advice on compiling a c++ project to a standalone console executable


orbs
 Share

Recommended Posts

for a savvy c++ developer, how hard would it be to compile this into a standalone Win32 console executable?

i have almost no experience with c++ (and i have no need for any more, since i have AutoIt for pretty much all my requirements). i can compile a simple "hello world" executable (and even embed the mfc dll for backward compatibility). but i am quite interested with that project. your opinion?

 

P.S. this relates to AutoIt quite simply - once (if and when) i have that project as a standalone executable, i have a GUI made with AutoIt to execute it, then post-process and display the output.

 

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

Not hard. I already did the c# version. It’s extremely fast. With the C-sharp version you can run it right from auto IT as well. It’s actually a DLL for both and the test just uses that. 

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

so i looked into building the cpp dll, but it's deprecated and VERY slow because in the port they used a dependency for QT library. They are not maintaining support. I have the C# stuff built, and using @LarsJ threads on running compiled .NET code, this could work for you. this is a visual studio project. The zip is too big to fit here though. Let me know if you want it. I can enable a OneDrive link for the download.

 

Capture.png

just updated it to use .net 4.7.2 and now it's even faster... lol, love this. makes a usable dll

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

ok, got something working. with the console app you can specify two files to compare, and they can contain paths if needed (unless running where files are located of course)in su and you can pipe the console output or capture it.

this contains Speedtest.exe and DiffMatchPatch.dll. 

runs on windows 10, not tested elsewhere, build with .NET 4.7.2, should work on out of box 4.6

 use it like this or capture the output, your choice, but all they offer with this is html diff results

to pipe it to a file

speedtest SpeedTest1.txt SpeeTest2.txt > diffs.html

or plain console output

speedtest SpeedTest1.txt SpeeTest2.txt

one more thing, needs work on validating args, so if you feed it two you are ok with my simple checker, problem is, if one of those files is misspelt, then it will CRASH, lol, can be fixed. need input.

using dotnetcore to build this you could make it run native on many Linux distros, including all the big names and lots of little ones. i just used the google test cs app... lol and modified for my purposes. but that is how i roll, don't like re-inventing stuff.

to distribute or use, you only need the EXE, the DLL file

 

 

DiffMatchPatch_SpeedTest.zip

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

just to let you know, building the cpp one is no-go, it's based on QT and the redist is not on git anywhere anymore, I think they took it down. so it's C#, or Python or other languages. I already have the C# dll

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

thank you @Earthshine for this incredible work.

i must confess, what you have done is waaaaaaay over my head. therefore i limit myself to the conceptual aspect. i have downloaded and tested your code, and some questions do arise:

* the dll you build - can it be called directly from AutoIt using DllCall()? if so, how? and would it return an array of elements (which can be post-processed), or the final HTML formatted output?

* the diff demo has some post-diff cleanup settings which can be configured: Semantic, Efficiency, or none. as per my tests, your compilation seems to be using no cleanup. the demo offers Semantic cleanup which is better for human readability, and Efficiency cleanup (with edit cost of 4 by default, but with 5 it seems identical to Semantic). when i read the source code for the C# library, i see that these behaviour settings have default values (lines 181 to 201), and that these can be set by the calling process (line 183). have you some idea how to pass custom values to the dll for these settings?

PS. when you build the dll, the "File description" property has a typo ("DiffMatchPach" - missing a "t" for the "Patch" part). is this you, or is this specified somewhere in the source code? not that i mind so much, i'm just trying to figure out the logic of things.

PS2. i initially opted for C++ rather than C# because i'm allergic to anything dependent on .NET (being a sysadmin and all ;)). have you any information on whether this compilation has indeed .NET dependency, and if so, which version?

 

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

I don't think you can use DllCall() on this, as it's a .NET DLL

I have not yet figured out if it can be called direct by AutoIT, as I have tried using @LarsJ dotnet UDF

we can make the console app better to allow the configuration settings, let me look into that. Also the argument checking and validation need serious attention in the console app to make it usable, and we can add args to make those settings changes you wanted if we can.

I can easily add this line of code to console for you

diff_cleanupSemantic(diffs);

It's in Speedtest.cs, if you change that, we can get you to build it (.NET built in compiler if you you have .NET installed) and run that console app.

 

 

 

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

i also noticed this: https://www.nuget.org/packages/Diff.Match.Patch/

someone has compiled a dedicated version of the dll for every version of .NET available. is that insane? tell me that's not insane.

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

it's good, because some people or organisations stay on a certain one sometimes, so, I like the idea. My dll is the google code dll, but you can use thiers and modify the console app to your liking. I will help with that of course. so let me work on those changes to the console until we figure out how to use them direct. I built mine with the latest .NET available to me. 4.7.2, they just depend on 4.5, which is cool because it will run on 4.5 and up.

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

so i am going to update the .cs file and exe output to the post above, it includes those things you wanted to make it more readable

// Copyright 2010 Google Inc.
// All Right Reserved.

using DiffMatchPatch;
using System;
using System.Collections.Generic;




public class Speedtest
{
    public static void Main(string[] args)
    {
        //       string text1 = System.IO.File.ReadAllText("Speedtest1.txt");
        //       string text2 = System.IO.File.ReadAllText("Speedtest2.txt");

        if (args.Length < 2)
        {
            Console.WriteLine(value: "ERROR: args = null please provide two valid files you wish to compare.");
            /*            if (IsLinux())
                        {
                            Console.WriteLine(value: "Example: list / *.cpp");
                        }
                        else
                        {
                            Console.WriteLine(value: "Example: list c:\\ *.dll");
                        }
            */
        }
        else
        {

            string text1 = System.IO.File.ReadAllText(args[0]);
            string text2 = System.IO.File.ReadAllText(args[1]);

            diff_match_patch dmp = new diff_match_patch();
            dmp.Diff_Timeout = 0;

            var diffs = dmp.diff_main(text1, text2);
            dmp.diff_cleanupSemantic(diffs);
            var html = dmp.diff_prettyHtml(diffs);

            Console.WriteLine(html.ToString());

        }
    }
}

as you can see the input arguments should be properly validated and that needs to happen still,

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

Some good news, I was able to figure out, thanks to @Larsj -- that you can pass arrays of arguments to .NET code. So I think we can load DiffMatchPatch.cs into memory (compiles it on the fly) and then use the class in AutoIt

I just need to get a list of the DLLs it needs to load so I can test it, then you can call whatever method you want direct from AU3

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

I have tried everything, but I think it won't work direct because I can't represent the return value of diff_main method properly, but using the console exe and the dll together, this gets the string, you could regex it and get out all the data. I have included this file in the zip, called SpeedTestWrapper, all this is just development, can be altered and beefed up per specs if given.

#include <Array.au3>

Opt("MustDeclareVars", 1)
Example()

Func Example()
    Local $iPID = Run(@ComSpec & " /c Speedtest.exe SpeedTest1.txt SpeedTest2.txt > test.html")

    Local $oDiffs = FileReadToArray ("test.html")
    _ArrayDisplay($oDiffs)
EndFunc

I updated my post above to include what's necessary

https://www.autoitscript.com/forum/applications/core/interface/file/attachment.php?id=60787

you won't need the DiffMatchPatchTest.exe, all that does is unit test the DLL, at the console it should return "All Tests Passed" you can ignore that cs file and exe

 

Like I said, the speedtest.cs can be renamed to what you want, and we can beef up the arguments passed so you can totally configure the diff produced, which is only html in a string for you to parse

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

@Earthshine, i'm sorry i cannot contribute to that work you have done - which is awesome!

myself being reluctant of dependencies, and of not understanding or being able to maintain the code, i took a different path - that of the python. the GitHub repository includes the library in many languages, python being one of them, and i discovered python is surprisingly easy to learn (definitely so for AutoIt users). so i created a python program, compiled it to a single exe with its only dependency is the msvcr dll - the one shipped with Windows XP SP2 works out of the box - so no compatibility issues. now working on the command line arguments parsing - also not hard. i will post what i have when done (and when it doesn't look like spaghetti code :-)

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

i did a lot of python in TestComplete, my little logger rules. if you want it, you can have it. here it is. I hope you find it as useful as I did. I basically got it from the logging example in their help documentation and I think it was gold... worked great. your scripts just import from logging

import logging
from logging import NullHandler
import Const

def startLog(name):
  logger = logging.getLogger(name)
  logger.setLevel(logging.DEBUG)
  # create file handler which logs even debug messages
  fh = logging.FileHandler(Const.TD_LOGFILE)
  fh.setLevel(logging.DEBUG)
  # create console handler with a higher log level
  ch = logging.StreamHandler()
  ch.setLevel(logging.ERROR)

  ch1 = logging.StreamHandler()
  ch1.setLevel(logging.WARN)
  # create formatter and add it to the handlers
  formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  ch.setFormatter(formatter)
  ch1.setFormatter(formatter)
  fh.setFormatter(formatter)
  # add the handlers to logger
  logger.addHandler(ch)
  logger.addHandler(ch1)
  logger.addHandler(fh)    

  return logger

I call that LogUtil.py

 

then you can use this to log all the arguments passed to your functions, I love Reflection! a real OOP like Python rules

from os import sys
sys.path.append('C:\\Python34x86\\Lib\\site-packages')
import psutil
import logging
import Const
import inspect
import datetime
import time


def delay(seconds):
  Delay(seconds)
  
def logArgValues(frame):
  args, _, _, values = inspect.getargvalues(frame)
  for i in args:
    try :  
      Log.Message ("    %s = %s" % (i, values[i]))    
    except :
      pass
  return

with the logger, you just use it like this

logger.Message(log message text here)

logger.Warning(log message text here)

logger.Error(log message text here)

logger.Trace(log message text here)

you can totally customize the logger to include TRACE, currently only implemented Warning, Debug and 

 

Object oriented languages are my favorite for a reason.

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

whoa, that's still a bit over my head (again...) - but i might revisit that if and when i get to something that needs decent logging... meanwhile, what i did for this project is a tad bit more simple. it accepts two files as parameters, passes them to the diff-match-patch library, and reformats the output:

''' arguments:
if <2 or >3 : show general help & exit 9
if error reading #1,#2 : show specific cause & exit 8,7
if #3 not specified : output to stdout
if #3 specified but error opening it for writing: show specific cause & exit 6
'''

msg_help=""

msg_help+="\n"
msg_help+="program:   diffdmp.exe\n"
msg_help+="type:      Win32 console application\n"
msg_help+="version:   1.0\n"
msg_help+="\n"
msg_help+="purpose:   compare two text files (typically two versions of a text) using\n"
msg_help+="           the diff-match-patch library, with semantic cleanup. produce an\n"
msg_help+="           ordered list of additions, removals and identical text sections\n"
msg_help+="           which allows for clear presentation of the differences, as well\n"
msg_help+="           as recreating each of the texts.\n"
msg_help+="\n"
msg_help+="reference: https://github.com/google/diff-match-patch\n"
msg_help+="\n"
msg_help+="usage:     diffdmp.exe older_file newer_file [diffs_file]\n"
msg_help+="\n"
msg_help+="arguments: older_file : the first file to diff (typically the older version).\n"
msg_help+="           newer_file : the other file to diff (typically the newer version).\n"
msg_help+="           diffs_file : [optional] where to output the result. default=stdout"

import sys

if len(sys.argv)<3 or len(sys.argv)>4:
    print(msg_help)
    sys.exit(9)

try:
    text1 = open(sys.argv[1]).read()
except IOError:
    print("Error reading the older file:",sys.argv[1])
    sys.exit(8)

try:
    text2 = open(sys.argv[2]).read()
except IOError:
    print("Error reading the newer file:",sys.argv[2])
    sys.exit(7)

if len(sys.argv)==4:
    try:
        diffs_file=open(sys.argv[3],"w")
    except IOError:
        print("Error writing to diffs file:",sys.argv[3])
        sys.exit(6)
else:
    diffs_file=sys.stdout

'''
main function
'''

import diff_match_patch as dmp_module

dmp = dmp_module.diff_match_patch()
dmp.Diff_Timeout = 0.0
  
diffs = dmp.diff_main(text1, text2, False)
dmp.diff_cleanupSemantic(diffs)

'''
output
'''

diffchar=["-","=","+"]

for diff in diffs:
    print(diffchar[diff[0]+1]+str(len(diff[1]))+":"+diff[1], end='', file=diffs_file)

i wrote this with python 3.4 on Windows XP (clean installation with SP2), then compiled it with PyInstaller (made a resource file with version details in it and stuff, added a simple cmd icon) - and it works! and no messing about with compatibility of dependencies! even with a rather old msvcr*.dll it works out of the box!

me be happy.

P.S. will test further to see if adjustment of parameters is needed, if so i can easily add them to the arguments parsing routine.

P.S.2 if you see anything extremely dumb in my code above, do feel free to point it out. my first python script and all...

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

got it a bit updated. code and compiled executable in this SourceForge project.

i'm planning to integrate it into this:

 

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...