Pelles C forum

C language => Expert questions => Topic started by: EdPellesC99 on April 21, 2010, 05:21:26 PM

Title: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 on April 21, 2010, 05:21:26 PM
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
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: JohnF on April 21, 2010, 05:40:14 PM
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
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: frankie on April 22, 2010, 02:36:16 PM
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");
}

}
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 on April 22, 2010, 06:01:07 PM

  Thank you both very much for your answers.

   I will take a day and digest this ! 

   Much appreciated.   Ed 
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 on April 24, 2010, 01:29:19 AM
   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


Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 on April 24, 2010, 01:39:03 AM

  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
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: TimoVJL on April 24, 2010, 07:43:10 AM
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.
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: JohnF on April 24, 2010, 09:18:53 AM
 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
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: sapero on April 24, 2010, 03:29:28 PM
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);
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 on April 24, 2010, 05:54:44 PM

  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

'' ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: JohnF 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

Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: AlexN 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.
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: JohnF on April 25, 2010, 12:25:48 PM
Alex, I was trying to encourage him to find that out himself. :)

John
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 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
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: JohnF 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
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 on April 26, 2010, 05:31:29 PM
John,

  Yes it compiles without the define (I find this morning).

I thought I commented that define, and compile failed yesterday !

Guess it was a brain cramp instead :)
Thanks.
Title: Re: Does use of Strsafe functions not allow a console application compile?
Post by: EdPellesC99 on April 26, 2010, 06:10:30 PM
Winding this thread up, I want to emphasize the fact that all examples I had found (everywhere) using safe string functions - use the TCHAR datatype.
  Yesterday I found:
http://msdn.microsoft.com/en-us/library/7dzey6h6(VS.80).aspx

To simplify code development for various international markets, the Microsoft run-time library provides Microsoft-specific
"generic-text" mappings for many data types, routines, and other objects. These mappings are defined in TCHAR.H.
You can use these name mappings to write generic code that can be compiled for any of the three kinds of character sets: ASCII (SBCS), MBCS, or Unicode,
depending on a manifest constant you define using a #define statement.

Generic-text mappings are Microsoft extensions that are not ANSI compatible.


'' ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •
So this is why, using the TCHAR data type, you must compile with the -Ze option.
  I see now that using this data type has it's purpose ..... it is just a bit more involved.
'' ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •

So, as a variation here is my complete file that is based on the CHAR data type, you still must compile with the -Ze option.
This reiterates what Timo  said earlier, that when using the windows.h header you should enable Microsoft extentions.

Code: [Select]
#include <windows.h>
#define arraysize 75
//#define strsafe_no_deprecate
// apparently the above define is the default
#pragma comment (lib, "strsafe.lib")
#include <strsafe.h>
// // ~ This now compiles with Pelles C / Simple Console App, ! Required: -Ze option on compiler
// // ~ •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •  •

int main()
{
char pszDest[arraysize];
int cchDest = sizeof(pszDest)-1;

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

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

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

return 0;
}


Thanks everyone for your much appreciated help !

----------------------------Ed
  :)