Author Topic: TCLib discussion  (Read 4443 times)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1980
    • zapsolution
TCLib discussion
« on: October 15, 2021, 10:07:09 am »
Fred

Thank you very much for your very detailed TCLib post series!

About size reduction, you can also have a look at this thread
http://www.objreader.com/index.php?topic=91.0
In its final version it it is able to produce a small zTrace64.dll of only 10752 bytes following the suggestion of Andrey Unis.

Linking only with these
Additional Dependencies kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;
Ignore All Default Libraries YES(NODEFAULTLIB)




« Last Edit: October 15, 2021, 10:36:09 am by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Frederick Harris

  • Newbie
  • *
  • Posts: 47
Re: TCLib discussion
« Reply #1 on: October 16, 2021, 06:14:58 am »
You know, for some stuff I just 'dumb' my way through it.  Not everything, mind you, but for some stuff.  Take COM, for example.  I knew from the start it would be hard, very hard.  So hard in fact, that I may fail to grasp it.  So that is something I didn't dumb my way through.  I worked hard on it, read every book, and devoured all the documentation.

But compiling from the command line with Visual Studio is something I just dumbed my way through.  Never studied up on it much.  There's actually like seven selections on Visual Studio 2019's Start Menu for a command line session.  Only two of them made any sense to me.  Those two specifically mentioned building x86 code or x64 code.  One of the other selections, and actually the top one, which I believe you chose Patrice, says something to the effect "Developer Command Prompt For Visual Studio".     Now, in my mind I have to admit, that does sound good.  But what goes through my mind when I read it, is "a black command line window is going to come up staring me in the face, with an intimidating cursor sitting there blinking at me in an impatient fashion, and somehow or other I'm going to have to tell it whether to build x86 code or x64 code, and somewhere in gigabytes of Microsoft documentation there are listings of command line switches describing how to specify that, and since I'm dumbing my way through it, I don't have a clue what they are, and I'm too lazy to look for them, so I don't think I want to choose that - at least not while there are two obvious selections there that specifically specify building x86 or x64 code ! :) 

And as for those other funny choices about x86_ARMx64 cross tools and ARMx64_x86 cross tools - I don't have a CLUE what that means! 

Well, I do now!  In about 30 seconds of searching I came up with this link that describes it all!  :)    ....

https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-160

Been wondering for years what all that 'cross tools' stuff was about - probably since I first saw it with Visual Studio 2008!  I took the 16 minutes it says it takes to read it and now I'm not dumbing my way through it anymore!  I'm quite the expert on it now, bathing in the brilliant light of truth and knowledge, if I do say so myself! :)  All I really need to do now is follow James lead and learn to use batch files a bit better and there will be no stopping me!  :)

Here's the TRUTH scribbed on the golden tablets...

Code: [Select]
Command File                 Host and Target architectures
=======================================================================
vcvars32.bat            Use the 32-bit x86-native tools to build 32-bit x86 code.
vcvars64.bat            Use the 64-bit x64-native tools to build 64-bit x64 code.
vcvarsx86_amd64.bat Use the 32-bit x86-native cross tools to build 64-bit x64 code.
vcvarsamd64_x86.bat Use the 64-bit x64-native cross tools to build 32-bit x86 code.
vcvarsx86_arm.bat Use the 32-bit x86-native cross tools to build ARM code.
vcvarsamd64_arm.bat Use the 64-bit x64-native cross tools to build ARM code.
vcvarsx86_arm64.bat Use the 32-bit x86-native cross tools to build ARM64 code.
vcvarsamd64_arm64.bat Use the 64-bit x64-native cross tools to build ARM64 code.
vcvarsall.bat        Use parameters to specify the host and target architectures, Windows SDK, and platform choices. For a list of supported options, call by using a /help parameter.

I spent some time this evening while watching CNN tracking down the locations of some of these vcvarsXXXXXXX.bat files that the shortcuts on the Start Menu point to, and I put together this little file with the name of the batch file, and it's actual contents if you open the thing.  Fact is, these are all really little files comprising only a few bytes.  Here are the names of the file and their contents....

Code: [Select]
vcvars32.bat         contents   >>>>   @call "%~dp0vcvarsall.bat" x86 %*
vcvars64.bat         contents   >>>>   @call "%~dp0vcvarsall.bat" x64 %*
vcvarsamd64_x86.bat  contents   >>>>   @call "%~dp0vcvarsall.bat" x64_x86 %*
vcvarsx86_amd64.bat  contents   >>>>   @call "%~dp0vcvarsall.bat" x86_x64 %*

As you can see, they all call vcvarsall.bat passing in various parameters.  I can only barely follow it.  I bet James understands it all perfectly.  That's the stuff I need to study up on.  If you want to see some really nasty looking stuff, check out vcvarsall.bat. 
« Last Edit: October 16, 2021, 10:00:04 am by Frederick Harris »

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1980
    • zapsolution
Re: TCLib discussion
« Reply #2 on: October 16, 2021, 10:08:01 am »
Thank you for the link, it is very instructive!
Patrice
(Always working with the latest Windows version available...)

James Fuller

  • Newbie
  • *
  • Posts: 41
Re: TCLib discussion
« Reply #3 on: October 16, 2021, 05:14:04 pm »
Fred,
  An Excellent new link posted just a couple weeks ago.
I worked most of this out on my own and I think I got most of it correct for my purposes but I will read this more closely shortly.

James

Frederick Harris

  • Newbie
  • *
  • Posts: 47
Re: TCLib discussion
« Reply #4 on: October 16, 2021, 05:35:31 pm »
Yea, I noted how recent that MS link was too James.  Couple weeks ago when we were conversing again I did a search looking for batch file tutorials.  I found a couple and bookmarked them.  I'm hoping to study up on them real soon, then take a good look at your BCX work.  Batch files have always been a weak topic for me.  I know most programmers are pretty knowledgable about them.  So it would do me good.

For example, here is the contents of the batch file that executes when I execute the shortcut for x64 command line work....

@call "%~dp0vcvarsall.bat" x64 %*

It's pretty clear to me it's calling another batch file named vcvarsall.bat, and passing in the 'x64' argument to set up the environment for x64 builds.  But there are a lot of symbols there of which I have no idea of their meaning or significance, such as....

Code: [Select]
@call       << the meaning of the @call symbols
%~dp0   << the meaning of the '%' stuff
x64 %    << more of the '%' stuff

I guess you are familiar with these things?  Do you know of a good source of learning of this sort of thing?

I do understand some of this stuff.  For example, I recall years ago having to set up my environment on an XP machine for working with HLA - High Level Assembler.  I recall manually setting up LIB, INCLUDE, BIN, etc., environment variables so the compiler/assembler would work.  Otherwise, I don't usually fool with this kind of stuff.

Frederick Harris

  • Newbie
  • *
  • Posts: 47
Re: TCLib discussion
« Reply #5 on: October 16, 2021, 06:46:06 pm »
From the other thread Patrice said....

Quote
Yes, but this is really not something easy to figure what to do, and i have to keep track of this thread for the next time

I feel bad you had that unfortunate 'run in' with the nmake error and conflict between x86 builds and x64 builds Patrice, but I really don't understand why you think building TCLib from the command line is hard to do.  To me, the very hardest most error prone part of it is use of the old command prompt CD commands (Change Directory), which admittedly require one to enter a whole series of symbols - letters, at the keyboard, with zero tolerance for mistakes.  But then as coders we pretty much have to do that all day long, don't we?  It's one of the reasons I tend to keep all my code in short folder paths not too far off the C:\ root directory.  Nothing I hate worse than having to type long directory paths that reach from one end of the screen to the other.  God, how thankful I was when Microsoft finally did away with "C:\Documents and Settings" in favor of just "C:\Users"!

Otherwise, if one chooses the right shortcut to the right batch file, all it takes to make TCLib is type...

nmake TCLib.mak

Of course, if one isn't used to using make files that's one conceptual hurdle to overcome.  I can't really say I'm an expert on those either.  My TCLib is actually the only place I use them, and the reason for that is that in my original studies of Matt Pietrek's LibCTiny.lib, and his download of it, he used them and my TCLib.mak is just an adaptation of his.  But it completely makes sense in this context because of the many *.cpp files that need to be built.  In terms of background on Make files - and I'm just mentioning this because in the Windows coding ecosystem they don't seem to be as heavily used by most coders as in the *.nix coding ecosystem, I believe the whole concept was created by Richard Stallman, who was pretty much the original creator of everything GCC used in the *.nix world.  That was a time in the 80s when processor wise everything was slow.  And folks in those times were building major software like operating systems and compilers which involved myriads of files and hundreds of thousands of lines of code.  It could take hours or even days for compilations of everything to occur from scratch.  So Stallman created make in such a way that it started at the end of the make file working backwards and checked source code file times against obj file times, and only rebuilt files where times were different, i.e., someone made a modification to source somewhere.  In that way build times were reduced so only the code that needed to be rebuilt was rebuilt.  One thing you mentioned Patrice was the need to delete the obj files from a failed attempt to build the library.  I believe that's a side effect of what I just described.  When I run nmake to build TCLib I always start with a 'clean' directory with no binaries in it.  That way nmake knows it has to rebuild everything from scratch.  That way no logic will execute in nmake that can come to erroneous conclusions about what needs to be done.   

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1980
    • zapsolution
Re: TCLib discussion
« Reply #6 on: October 16, 2021, 07:04:14 pm »
That reminds me the old Microsoft PDS 7.1 command line from 1990

Major utilities:

    -  Microsoft Segmented-Executable Linker (LINK)
    -  Microsoft Library Manager (LIB)
    -  Microsoft Program-Maintenance Utility (NMAKE)

Nothing new under the sun.
Do you remember this
LIB TCLib -+new.obj

 
Patrice
(Always working with the latest Windows version available...)

James Fuller

  • Newbie
  • *
  • Posts: 41
Re: TCLib discussion
« Reply #7 on: October 16, 2021, 07:23:18 pm »

Frederick Harris

  • Newbie
  • *
  • Posts: 47
Re: TCLib discussion
« Reply #8 on: October 16, 2021, 07:58:18 pm »
No, don't remember that Patrice.  I never got PDS 7.1 until I was learning VB4 or so in mid 90s.  What happened with me is I started pretty early in DOS days of 80s and built all my software from scratch first with Bill Gates early versions of DOS Basic (interpreted), then later with QB 4.5.  I worked in forestry and I need programs to do all kinds of lengthy computations, and make fairly complex tables of outputs.  Once I got all my software written and working, like a decade went by where I was really not doing any coding.  Then I sold my business and took a job with the Pennsylvania Bureau of Forestry (goverment agency).  When I got there I soon found out my major use to them would not be as a forester, but as a programmer.  They had a tremendous need for custom forestry software of the type I had written for myself, but no one to write it.  And of course software and algorithms always fascinated me, dating back to my college days in the 1970s where I had to take an introductory course in computer programming which used Fortran on mainframes to teach algorithmic processes.  So I started building all kinds of software for them, which they really appreciated.

I remember PDS 7.1 very well though.  The biggest thing about it that completely blew my mind when I first encountered it was it's ability to create custom fonts.  Reason I say that is that the most intractable problem I had from my 1980s days that I simply didn't know how to solve was how to overcome the 80 X 25 or 80 X 43 DOS screen where my tables were limited to only 80 character cells across.  QuickBasic had graphic capabilities, and my intuition was that graphic font characters were the only answer, but at that time I didn't know how to create fonts on my own, or I simply never got into it.  Then years went by and it was the mid-90s and I discovered Visual Basic and I think I came by an illegal download of PDS 7.1, and discovered the font thing.  Even though it was old technology by that time in the mid 90s, I played with it a lot simply because it solved a problem I could never manage to solve on my own, and I was completely intrigued by it.

But the fact that I had as much DOS programming knowledge as I had really helped a lot even in the waning days of DOS, because in the 90s handheld data collectors were becoming a really big thing, and my organization really wanted to implement them into their massive field data collection processes, so as to improve efficiency.  At the time all our foresters collected field data on paper tally sheets, and mailed them into the central office, where a mainframe computer was used, and all the data was keypunched into the systems by two ladies, both of whom eventually developed carpel tunnel syndrone from all the keypunching.  The one had to go out on disability due to that and the pain it caused.  So the first couple years I worked for them all I did was implement DOS data collection software for the DOS data collectors we had.  Handheld data collectors were in my mind really the last stand for DOS.  By the mid 90s everybody was on Windows 3.1 then Win 95, but for handheld data collectors DOS was king.  Then by the late 90s Windows CE came along and I started doing that.

I guess really it was in those days that I learned to do stuff like building from the command line because to get QuickBasic to do strange stuff like call the DOS and BIOS interrupts, and extended custom interrupts created by the OEM data collector manufacturers, some stuff had to be done from the command line.  Then when I discovered Petzold and his Win 95 book, he had a bit in there on building his programs from the command line, which I tried with Visual Studio 98 and VC6, and I think he provided make files for all his programs.

   

So I see you are more familiar with this stuff than I thought. 

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1980
    • zapsolution
StringCchPrintf
« Reply #9 on: October 22, 2021, 07:17:56 pm »
Please could you tell me, what is the TClib replacement for StringCchPrintf ?
Patrice
(Always working with the latest Windows version available...)

Frederick Harris

  • Newbie
  • *
  • Posts: 47
Re: TCLib discussion
« Reply #10 on: October 23, 2021, 05:35:15 am »
I don't have any of the String Safe Functions implemented in TCLib Patrice.  It's about bedtime for me now, but I'll check on it first thing in the morning to see where they are implemented.  In MS Docs it mentions strsafe.h but doesn't mention which library is involved.  I'll check tomorrow.

Frederick Harris

  • Newbie
  • *
  • Posts: 47
Re: TCLib discussion
« Reply #11 on: October 23, 2021, 06:16:58 pm »
Just spent several hours looking at this.  It is a real 'can of worms' (colloquialism for a messy, nasty problem). 

On first thought, I assummed I might be able to load some dll where it might be implemented and do a GetProcAddress() on it and thereby obtain a pointer to it which might be used.  That's how TCLib implemented what printf family functions it contains.  That's a good deal if it can be done because the printf family of functions takes thousands and thousands of lines of code to implement.  They are varaidic functions taking a variable argument list, which makes them rather nasty to deal with.  But it appears implementations of those functions aren't in any dll....

https://stackoverflow.com/questions/54922292/is-stringcbprintf-strsafe-h-part-of-the-winapi

It's even arguable as to whether they are part of the C Runtime or Windows Api!  Nobody is quite sure!

Giving up on the idea of implementing them or it from a GetProcAddress() call, I gave some thought to implementing it myself.  That appears to be another real nightmare.  Below is a runnable test snippet that exemplifies the problem as I see it....

Code: [Select]
// cl Test1.cpp /O1 /Os /GS- /Gy /link TCLib.lib kernel32.lib
#include <windows.h>
#include "stdio.h"

HRESULT StringCChPrintf(LPTSTR pszDest, size_t cchDest, LPCTSTR pszFormat,  ...)
{
 printf("Called StringCChPrintf()!\n");
 printf("pszDest   = %p\n",pszDest);
 printf("cchDest   = %u\n",cchDest);
 printf("pszFormat = %s\n",pszFormat);
 
 return S_OK;
}

int main()
{
 char szBuffer[128];
 char* pStr="Here Is A String\n";
 HRESULT hr;
 
 printf("szBuffer   = %p\n",szBuffer);
 hr=StringCChPrintf(szBuffer,128,"%s",pStr);
 if(SUCCEEDED(hr))
 {
    printf("StringCChPrintf() Succeeded!\n");
 }
 getchar();
 
 return 0;
}

Output:
Code: [Select]
C:\Code\VStudio\VC19\StrSafe>test1
szBuffer   = 0000009E6A16F6F0
Called StringCChPrintf()!
pszDest   = 0000009E6A16F6F0
cchDest   = 128
pszFormat = %s
StringCChPrintf() Succeeded!

Note I renamed the function StringCChPrintf so it wouldn't conflict with any existing symbol (the real one is StringCchPrintf) the compiler might encounter somewhere.  In my StringCChPrintf you'll have a variable number of arguments and there could be additional string literals there too.  They need to be expanded according to the rules of the format specifiers and each written to the destination buffer, making sure current buffer write operations aren't exceeding the cchDest buffer.  Not trivial.  Likely the solution woyuld involve the _vsnprintf family of functions....

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vsnprintf-vsnprintf-vsnprintf-l-vsnwprintf-vsnwprintf-l?view=msvc-160

Any thoughts?  At the moment I'm not inclined to undertake this.  I've had a bad taste in my mouth over the secure printf family of functions since the early 2000s when I attempted to learn and use them.  At the time there were bugs in them that prevented my programs from working.  I'm thinking particularly of some ODBC Tutorials I posted in Jose's Forum, where I had to give up on the secure functions and just use the un-secure ones instead.  Since that time I haven't revisited the issue.

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1980
    • zapsolution
Re: TCLib discussion
« Reply #12 on: October 23, 2021, 06:25:33 pm »
Ok, i can work around it, using wcscpy and lstrcat

BTW, what is the name of the TCLib function to convert num to a WCHAR string?
Patrice
(Always working with the latest Windows version available...)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1980
    • zapsolution
Re: TCLib discussion
« Reply #13 on: October 24, 2021, 11:01:46 am »
Fred

I have used TCLib with the new WatchDog project (14 Kb), compiled from the environment.
Do you think using the command line would produce smaller code?
« Last Edit: October 24, 2021, 11:03:33 am by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Frederick Harris

  • Newbie
  • *
  • Posts: 47
Re: TCLib discussion
« Reply #14 on: October 24, 2021, 01:42:12 pm »
Quote
BTW, what is the name of the TCLib function to convert num to a WCHAR string?

Code: [Select]
// Test_01.cpp
// cl Test_01.cpp /O1 /Os /GS- /Gy TCLib.lib
// 4,096 Bytes TCLib
#include <Windows.h>
#include "stdio.h"
extern "C" int _fltused=1;

int main()
{
 double num = 3.14159;
 wchar_t szBuffer[64];
 
 swprintf(szBuffer,L"%f",num);
 wprintf(L"%s",szBuffer);
 getchar();
 
 return 0;
}

// Output:
// 3.141590
« Last Edit: October 24, 2021, 01:52:00 pm by Frederick Harris »