NO

Author Topic: Does use of Strsafe functions not allow a console application compile?  (Read 10021 times)

EdPellesC99

  • Guest
I am looking into the Strsafe functions, first ... for use in a console application.
using the tchar data type.

It looks to me that in order to use the
strsafe.lib, and strsafe.hand compile in PellesC, you MUST use windows.h and compile
as a win32.exe app and Link with Console as a subsystem.

Am I right?

Assuming this is correct, can anyone explain why I must use windows.h and compile as a Gui app with console as a subsystem to use the strsafe functions ?

Thanks Ed

JohnF

  • Guest
The problem maybe that you are trying to use TCHAR which is a windows type. Try this.

Code: [Select]
#include <stdio.h>
#define STRSAFE_LIB_IMPL
#include <strsafe.h>

int main(void)
{
wchar_t s[] = L"Hello World!";
wchar_t ss[90];
StringCchCopyW(ss, 90, s);
wprintf(L"%ls\n", ss);
return 0;
}

Or you can use TCHAR provided you include windows.h

Code: [Select]
#include <windows.h>
#include <stdio.h>
#define STRSAFE_LIB_IMPL
#include <strsafe.h>

int main(void)
{
TCHAR s[] = L"Hello World!";
TCHAR ss[90];
StringCchCopy(ss, 90, s);
wprintf(L"%ls\n", ss);
return 0;
}

John

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Doesn't seem very clear also from help.
But anyway you have to explicitely declare that you want the library extensions using the symbol "__STDC_WANT_LIB_EXT1__" set to 1 (see the example).
If you want to use the widechar functions (UNICODE) you have to use <windows.h>

Code: [Select]
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>

int __cdecl main(int argc, char **argv)
{
for (;;)
{

printf_s("This is a secure printf!\n");
}

}
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

EdPellesC99

  • Guest

  Thank you both very much for your answers.

   I will take a day and digest this ! 

   Much appreciated.   Ed
 

EdPellesC99

  • Guest
   John,

  I do not know what I might be doing wrong, but I cannot compile either of your versions.
  
 Does each version compile for you?  ..... If so maybe I need to figure that out.

  Here is a complete file that compiles for me if I compile as a Gui, and Console subsystem.

Code: [Select]
//--------------------------------------------------------------------------------------
#include <windows.h>
#include <tchar.h>
#define strsafe_no_deprecate
#pragma comment (lib, "strsafe.lib")
#include <strsafe.h>

int main()
{
// // ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •
int const arraysize = 75;

TCHAR pszDest[arraysize];

size_t cchDest = arraysize * sizeof(TCHAR);
LPCTSTR pszFormat = TEXT("%s %s %s %s");   // // ~ NOTE no commas between specifiers !
TCHAR *pszTxt = TEXT("Hello World.");
TCHAR *pszTxt1 = TEXT("I am struggling,");
TCHAR *pszTxt2 = TEXT("with");
TCHAR *pszTxt3 = TEXT("my simple Console App compile.");

StringCchPrintf(pszDest, cchDest, pszFormat, pszTxt, pszTxt1, pszTxt2, pszTxt3);

  printf("pszDest is:\n\n\"%s\"", pszDest);
getchar();

  return 0;
}

//------------------------------------------------------------------------------------------------



  I am using the latest PellesC downloaded setup. w/ Pelle's custom version of the lcc compiler.

  I know if your versions compile for you, I need to figure my problem out (but I do get over 100 warnings and errors).

   Thanks, Ed


« Last Edit: April 24, 2010, 03:55:17 AM by EdPellesC99 »

EdPellesC99

  • Guest

  frankie,

  I am afraid it could take me a whole lot of time to figure out how I would incorporate you code to help me.

  If you could edit my file listed in prior reply, to give me a clue as to how I could use your function to help me, I would appreciate it.

  Otherwise I am in trouble.... !

  Thanks, Ed

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Quote
I know if your versions compile for you, I need to figure my problem out (but I do get over 100 warnings and errors).
With <windows.h> you should use compiler option -Ze Enable Microsoft extensions.

Edit:
With <strsafe.h> use  compiler option -Ze Enable Microsoft extensions too.
« Last Edit: April 24, 2010, 10:07:39 AM by timovjl »
May the source be with you

JohnF

  • Guest
I do not know what I might be doing wrong, but I cannot compile either of your versions.

Ed, it would be a good idea to post what errors you get when trying to compile.

John

sapero

  • Guest
When compiling without optimizations (my custom, default setting), "const int" is working like regular integer, and the compiler returns "constant expected/unknown size" error (and forces external symbol to be included __chkstk). Replace it with #define.
Second typo is that you have used printf instead _tprintf:

Code: [Select]
#define arraysize 75
_tprintf(TEXT("pszDest is:\n\n\"%s\""), pszDest);

EdPellesC99

  • Guest

  I neglected to mention that I am using XP, SP2.

   Thank you all very much for your responses. I am in much better shape now.

'' ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •

Timo,
   The -Ze option was the golf "hole in one". Thanks. My complete file listed above immediately compiled.

  Thanks much, Ed
... I did see a reference to the /Ze switch in my errors, but I so often see wild clues in errors !!!!

'' ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •

John,

 
Yes, I should have listed the Output !
Ok, now that I know I should have used the -Ze option. I re-compiled each of
your samples. Mucho less problems, but no cigar yet.

So for Your first:



Code: [Select]
#include <stdio.h>
#define STRSAFE_LIB_IMPL
#include <strsafe.h>

// // ~ The problem maybe that you are trying to use TCHAR which is a windows type. Try this.
// // ~ Use one of following.

int main()
{
wchar_t s[] = L"Hello World!";
wchar_t ss[90];
StringCchCopyW(ss, 90, s);
wprintf(L"%ls\n", ss);
return 0;
}

'' ~ •  •  •  •  •  •  •  •  •  •  •  •

Output:
Building JohnF Tip1.obj.
Building JohnF Tip1.exe.
POLINK: error: Unresolved external symbol '_StringCchCopyW@12'.
POLINK: fatal error: 1 unresolved external(s).
*** Error code: 1 ***
Done.

'' ~ •  •  •  •  •  •  •  •  •  •  •  •
Then for your second recommendation:

Code: [Select]
#include <windows.h>
#include <stdio.h>
#define STRSAFE_LIB_IMPL
#include <strsafe.h>

int main(void)
{
TCHAR s[] = L"Hello World!";
TCHAR ss[90];
StringCchCopy(ss, 90, s);
wprintf(L"%ls\n", ss);
return 0;
}

'' ~ •  •  •  •  •  •  •  •  •  •  •  •

Output:
Building JohnF Tip2.obj.
C:\SGV1\C SafeString\Console\StringCchPrintf\Tips fr PF compileSimpleCon\JohnF Tip2.c(8): warning #2004: Compatibility of 'wchar_t' and 'char' is compiler dependent.
C:\SGV1\C SafeString\Console\StringCchPrintf\Tips fr PF compileSimpleCon\JohnF Tip2.c(11): warning #2234: Argument 2 to 'wprintf' does not match the format string; expected 'wchar_t *' but found 'char *'.
Building JohnF Tip2.exe.
POLINK: error: Unresolved external symbol '_StringCchCopyA@12'.
POLINK: fatal error: 1 unresolved external(s).
*** Error code: 1 ***
Done.


'' ~ •  •  •  •  •  •  •  •  •  •  •  •

John .....Soo much closer now that the -Ze option is being used. Thanks, any suggestions, after seeing current Output?

'' ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •

sapero,

  Ok I have corrected the _tprintf, and though I saw no warnings on the "constant expected/unknown size", I believe I have in other programs.

  So my new code, that compiles as a simple console app is:


Code: [Select]
#include <windows.h>
#include <tchar.h>
#define arraysize 75
#define strsafe_no_deprecate
#pragma comment (lib, "strsafe.lib")
#include <strsafe.h>
// This now compiles with Pelles C / Simple Console App, with additional Compiler option -Ze  !

int main()
{
TCHAR pszDest[arraysize];
size_t cchDest = arraysize * sizeof(TCHAR);
LPCTSTR pszFormat = TEXT("%s %s %s %s");   // // ~ NOTE no commas between specifiers !
TCHAR *pszTxt = TEXT("Hello World.");
TCHAR *pszTxt1 = TEXT("I am struggling,");
TCHAR *pszTxt2 = TEXT("with");
TCHAR *pszTxt3 = TEXT("my simple Console App compile.");

StringCchPrintf(pszDest, cchDest, pszFormat, pszTxt, pszTxt1, pszTxt2, pszTxt3);

_tprintf(TEXT("pszDest is:\n\n\"%s\""), pszDest);
getchar();
return 0;
}

If you, sopero, (or any of you guys) know where I could read up on the TCHAR data type let me know. I have had the impression it's use is falling out of favor (that it goes back to the days of windows 95). But I am not sure what datatype is "replacing" it (....if my impression is right).

   thanks much for your input, Ed

'' ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •
« Last Edit: April 26, 2010, 05:47:28 PM by EdPellesC99 »

JohnF

  • Guest
Re: Does use of Strsafe functions not allow a console application compile?
« Reply #10 on: April 25, 2010, 08:00:40 AM »
Ed,

Output:
Building JohnF Tip1.obj.
Building JohnF Tip1.exe.
POLINK: error: Unresolved external symbol '_StringCchCopyW@12'.
POLINK: fatal error: 1 unresolved external(s).
*** Error code: 1 ***
Done.


When you get 'Unresolved external symbol' it means the function was not found in any library that you have specified.

John


Offline AlexN

  • Global Moderator
  • Member
  • *****
  • Posts: 394
    • Alex's Link Sammlung
Re: Does use of Strsafe functions not allow a console application compile?
« Reply #11 on: April 25, 2010, 10:10:44 AM »
POLINK: error: Unresolved external symbol '_StringCchCopyA@12'.
POLINK: fatal error: 1 unresolved external(s).

You forgot
Code: [Select]
#pragma comment (lib, "strsafe.lib") to tell the linker to add the strsafe.lib.

In some examples before it was already used.
best regards
 Alex ;)

JohnF

  • Guest
Re: Does use of Strsafe functions not allow a console application compile?
« Reply #12 on: April 25, 2010, 12:25:48 PM »
Alex, I was trying to encourage him to find that out himself. :)

John

EdPellesC99

  • Guest
Re: Does use of Strsafe functions not allow a console application compile?
« Reply #13 on: April 25, 2010, 08:19:14 PM »
Thanks Alex, appreciate it.

---------------------------------------------------

John,

  I have the first suggestion working.
Code: [Select]
//#include <stdio.h>
#define STRSAFE_LIB_IMPL
#include <strsafe.h>
#pragma comment (lib, "strsafe.lib")
// // ~ The problem maybe that you are trying to use TCHAR which is a windows type. Try this.
// // ~ Use one of following.


int main(void)
{
wchar_t s[] = L"Hello World!";
wchar_t ss[90];
StringCchCopyW(ss, 90, s);
wprintf(L"%ls\n", ss);
getchar();
return 0;
}

  Can you help me understand why
#define STRSAFE_LIB_IMPL is necessary. Of course it will not compile without it.

  I have found in strsafe.h:
Code: [Select]
#elif defined(STRSAFE_LIB_IMPL)
#define STRSAFEAPI  _STRSAFE_EXTERN_C HRESULT __stdcall
#define STRSAFEAPIV  _STRSAFE_EXTERN_C HRESULT __cdecl
#else
#define STRSAFEAPI  __inline HRESULT __stdcall
#define STRSAFEAPIV  __inline HRESULT __cdecl
#define STRSAFE_INLINE
#endif

  How would you know this define is necessary?
It seems to have something to do with declaring the strsafe functions as Not Inline functions (?).
Thanks, Ed

JohnF

  • Guest
Re: Does use of Strsafe functions not allow a console application compile?
« Reply #14 on: April 26, 2010, 09:44:41 AM »
Ed, this will compile without that define

Code: [Select]
#include <strsafe.h>
#pragma comment (lib, "strsafe.lib")

int main(void)
{
wchar_t s[] = L"Hello World!";
wchar_t ss[90];
StringCchCopyW(ss, 90, s);
wprintf(L"%ls\n", ss);
getchar();
return 0;
}

Now, there are a lot of defines in strsafe.h and to be frank it is a bit of a mess. Anyway, one has to sometimes go through the relevant header and check the defines to see what is required.

John