Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Passing file path with ß to C function from DLL

129 views
Skip to first unread message

Alexandru

unread,
May 15, 2019, 5:03:40 AM5/15/19
to
Hi,

I have a C extension for Tcl which is compiled using:

Compile in console C:\msys\msys.bat:
cd "C:/mingw-w64/mingw64/bin"
gcc C:/c2tcl_src/checksum.c -shared -o C:/c2tcl_src/checksum.dll -DUSE_TCL_STUBS -IC:/Tcl/include -LC:/Tcl/lib -ltclstub86 -O3 -march=native

The main C function computes the checksum of the content of a file.

The corresponding Tcl function simply calls the C function like this

::checksum::FileContentChecksum filename

In C I use filename = Tcl_GetString(objv[1]); to get the file path from Tcl.

Everything works fine except when the file name contains "ß" and I suppose any other special chars. I suspect an issue with the char encoding, but I have no I idea how to solve it.

Interestingly, I don't get an error. I just get the same checksum "D41D8CD98F00B204E9800998ECF8427E" as a result, no matter what the file content is.

Any idea, how to solve this?

Many thanks!
Alexandru

Harald Oehlmann

unread,
May 15, 2019, 5:15:01 AM5/15/19
to
a) be sure that the Windows extension is compiled with Unicode enabled:
#define _UNICODE

b) After taking the string from Tcl_GetString(objv[1]), recode it to
UNICODE encoding and then pass it to the Windows API.

Tcl_DString sPar1;
char *pStr;
int lStr;
Tcl_DStringInit(& sPar1);
pStr = Tcl_GetStringFromObj(objv[PositionSPar],&lStr);
Tcl_WinUtfToTChar( pStr, lStr, &sPar1);

WinAPICallWitStringArgument( (TCHAR *)Tcl_DStringValue(& sPar1) );

Hope this helps,
Harald

Alexandru

unread,
May 15, 2019, 5:29:09 AM5/15/19
to
Hi Harald, thanks for the quick help.
I would like to try the "#define _UNICODE" first, but where should I set this option? I'm not really a C programer and I have little knowledge about C compiler.

I also tried to integrate your code snippet but I get an error about the WinAPICallWithStringArgument (implicit declaration). I guessed you mistyped WinAPICallWitStringArgument (without an h).

Harald Oehlmann

unread,
May 15, 2019, 7:08:15 AM5/15/19
to
place it above #include <windows.h>

>
> I also tried to integrate your code snippet but I get an error about the WinAPICallWithStringArgument (implicit declaration). I guessed you mistyped WinAPICallWitStringArgument (without an h).
>
No, "WinAPICallWitStringArgument" is your api-call to open the file.


Alexandru

unread,
May 15, 2019, 7:24:16 AM5/15/19
to
I tried your original code too, but I get warning implicit declaration of the function. Should I load some special libraries? I can't find anything with google on this.

Alexandru

unread,
May 15, 2019, 7:33:18 AM5/15/19
to
Am Mittwoch, 15. Mai 2019 13:08:15 UTC+2 schrieb Harald Oehlmann:
>
> place it above #include <windows.h>
>
> >

I found C:\mingw-w64\mingw64\x86_64-w64-mingw32\include\windows.h and added #define _UNICODE, but the result is still the same after new compilation.

So I'll try to integrate your code snippet.

Alexandru

unread,
May 15, 2019, 7:48:29 AM5/15/19
to
Am Mittwoch, 15. Mai 2019 13:08:15 UTC+2 schrieb Harald Oehlmann:

> No, "WinAPICallWitStringArgument" is your api-call to open the file.


Look like your code snippet is working now.
Now I must convert the Tcl_DString to char, in order to pass it to the checksum function. I did some research an found Tcl_DStringResult but this also returns a Tcl_DString... How can I convert the types here?

Rich

unread,
May 15, 2019, 10:15:51 AM5/15/19
to
You /may/ want to look at the manpage for the Tcl_FSGetNativePath()
C level function.

Alexandru

unread,
May 15, 2019, 11:57:35 AM5/15/19
to
Thanks Rich but I don't see how that function could help in converting Tcl_DString to a normal string.

Rich

unread,
May 15, 2019, 12:28:11 PM5/15/19
to
It does not, it replaces your dstring mess.

You use it to retreive, from a Tcl_Obj, a representation of a path
suitable to pass into the OS filesystem API's. Which unless I'm
mistaken, seems to be your request. You've got a Tcl string that you
want to obtain a suitable char * style string for passing to open() or
fopen().

Ralf Fassel

unread,
May 15, 2019, 1:05:11 PM5/15/19
to
* Rich <ri...@example.invalid>
--<snip-snip>--
| >> You /may/ want to look at the manpage for the Tcl_FSGetNativePath()
| >> C level function.
| >
| > Thanks Rich but I don't see how that function could help in
| > converting Tcl_DString to a normal string.
>
| It does not, it replaces your dstring mess.
>
| You use it to retreive, from a Tcl_Obj, a representation of a path
| suitable to pass into the OS filesystem API's. Which unless I'm
| mistaken, seems to be your request. You've got a Tcl string that you
| want to obtain a suitable char * style string for passing to open() or
| fopen().

The key point here seems to be that on Windows Tcl_FSGetNativePath()
returns a wchar_t when _UNICODE is defined at compile time (which it
usually is when compiling TCL on Windows).

The wchar_t basically is a 16-bit unicode representation of the path,
allowing for the complete range of unicode characters in the filename.

This is important if the filename contains characters not representable
in the current system encoding codepage, since these chars then get
replaced by "?" and thus the fopen(char*) fails, while the
_wfopen(wchar_t*) succeeds.

R'

Alexandru

unread,
May 15, 2019, 2:11:06 PM5/15/19
to
Okay, so from the help I read "Tcl_FSGetNativePath(pathPtr) ". What is pathPtr? is it the pointer to a C string? Or is it objv[1]? I

Rich

unread,
May 15, 2019, 3:30:04 PM5/15/19
to
Passing in a Tcl_Obj pointer seems to work. For a custom C extension I
created for myself, I had to use this function to "get" a C string out
of a Tcl string that would work to fopen() (or open()) a file at the C
level, but only when the file contained non plan 7-bit ASCII
characters. For file names that contained 7-bit ASCII characters, I
did not have to do anything special.

I encountered the effect much like I suspect you did. Everything is
working, for quite some time, then suddenly, "file not found" out of
the blue. Turns out that first "file not found" was the first instance
of a filename with something other than plain 7-bit ASCII characters
that my extension had encountered.


Christian Gollwitzer

unread,
May 15, 2019, 4:41:20 PM5/15/19
to
Am 15.05.19 um 11:03 schrieb Alexandru:
> I have a C extension for Tcl [...]
> In C I use filename = Tcl_GetString(objv[1]); to get the file path from Tcl.
>
> Everything works fine except when the file name contains "ß" and I suppose any other special chars. I suspect an issue with the char encoding, but I have no I idea how to solve it.


You already got an answer from Harald. Beware that this is an idiotic
Windows problem. Under (modern) Linux and OSX, the standard file
functions in C like fopen() expect the file name as an UTF8 string. On
Windows, fopen() eexpects the file name in an 8bit encoding. Now
obviously in 8 bit you can't encode every possible file name. In order
to open and read a file in Windows you need to use special Windows
functions which are, of course, not available on the other platforms. So
you might want to include some #ifdef's to sort out the odd platform.

>
> Interestingly, I don't get an error. I just get the same checksum "D41D8CD98F00B204E9800998ECF8427E" as a result, no matter what the file content is.
>

That probably just means that the C function doesn't do error handling
on the file name, reads an empty string and hashes that.

Christian

Alexandru

unread,
May 16, 2019, 12:14:37 AM5/16/19
to
I think I will try to pass a file identifier from Tcl's open command to the C function instead. Thanks all of you for the great help.

Ralf Fassel

unread,
May 16, 2019, 4:40:44 AM5/16/19
to
* Alexandru <alexandr...@meshparts.de>
| Okay, so from the help I read "Tcl_FSGetNativePath(pathPtr) ". What is
| pathPtr? is it the pointer to a C string? Or is it objv[1]? I

The TCL manpages always defines the arguments later in the text in the
ARGUMENTS section. In this case:

const void *
Tcl_FSGetNativePath(pathPtr)
[...]

ARGUMENTS
[...]
Tcl_Obj *pathPtr (in) The path represented by this value is used for the operation in
question. If the value does not alreadyhave an internal path
representation, it will be converted to have one.

HTH
R'

Alexandru

unread,
May 16, 2019, 5:02:25 AM5/16/19
to
Thanks Ralf for the hint. For me it still sounds too cryptic. But I will see how I can solve the issue with these informations.

Alexandru

unread,
May 17, 2019, 4:43:50 PM5/17/19
to
Am Mittwoch, 15. Mai 2019 16:15:51 UTC+2 schrieb Rich:
Here is how try to get the native path, but there is no change, same wrong result:

Tcl_Obj *path;
char* filename;
path = objv[1];
Tcl_FSGetNativePath(path);
filename = Tcl_GetString(path);

Any idea what I'm doing wrong?

Rich

unread,
May 18, 2019, 3:39:57 PM5/18/19
to
char* filename;
filename = Tcl_FSGetNativePath(objv[1]);

Alexandru

unread,
May 19, 2019, 12:36:36 PM5/19/19
to
Am Samstag, 18. Mai 2019 21:39:57 UTC+2 schrieb Rich:
> > Here is how try to get the native path, but there is no change, same wrong result:
> >
> > Tcl_Obj *path;
> > char* filename;
> > path = objv[1];
> > Tcl_FSGetNativePath(path);
> > filename = Tcl_GetString(path);
> >
> > Any idea what I'm doing wrong?
>
> char* filename;
> filename = Tcl_FSGetNativePath(objv[1]);

If I do the above, I get the warning

warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]

I changed the declaration

char* filename;

to

const char* filename;

and I the warning disappears but the result of the checksum function is now wrong, even if the paths contains not special chars.

Furthermore, the man secifies "const void*" as a return value of Tcl_FSGetNativePath. Actuall I need a string not a void. I have no idea how this might work...

Ralf Fassel

unread,
May 20, 2019, 8:35:51 AM5/20/19
to
* Alexandru <alexandr...@meshparts.de>
| const char* filename;
>
| and I the warning disappears but the result of the checksum function
| is now wrong, even if the paths contains not special chars.

Can you show the complete C code, from Tcl_FSGetNativePath() up to how you
call the command to calculate the checksum and finally obtain the result?

| Furthermore, the man secifies "const void*" as a return value of
| Tcl_FSGetNativePath. Actuall I need a string not a void. I have no
| idea how this might work...

A "const void*" can be casted to any const data type required.
On Windows, in *should* resolve to a "wchar_t*", and you should use the
returned "const void* value in a *W type of Windows API function,
i.e. one requiring a wchar_t* instead of a char*.

I say 'should resolve to wchar_t' because the exact type of TCHAR on
Windows depends on whether _UNICODE is defined at compile time or not
(see MSDN for details).

R'

Alexandru

unread,
May 20, 2019, 9:30:07 AM5/20/19
to
Here is the function:
https://www.meshparts.de/download/software/checksum.c

The interesting part is in FileContentChecksum_Cmd

Thanks!

Ralf Fassel

unread,
May 21, 2019, 6:26:37 AM5/21/19
to
* Alexandru <alexandr...@meshparts.de>
| Here is the function:
| https://www.meshparts.de/download/software/checksum.c
>
| The interesting part is in FileContentChecksum_Cmd

Ok, that's simple enough (I have simplified a bit)

char* filename = Tcl_GetString(objv[1]);

FileContentChecksum(filename,checksum);
--<snip-snip>--

void FileContentChecksum(char* FileName, char* checksum) {

FILE *fd = fopen(FileName,"rb");

Tcl_GetString() gives you the string representation in the internal TCL
encoding (which is UTF-8 or something close to it). This uses two bytes
for the "ß" character. If you pass this to fopen(), you get an error,
since that file does not exist on disc on Windows.

If you instead call

wchar_t* fname = Tcl_FSGetNativePath(objv[1])
...
_wfopen(fname, ...)

https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2019

the file-open should succeed. Note that if you get a compiler warning
with the fname assignment, this might mean that your TCL was not
compiled for UNICODE (unlikely, but...).

As an alternative, you could convert the Tcl_GetString() result to
Windows System encoding, and then use fopen(), but this still has a
chance to fail if someones tries to open a file with characters in its
name which are not representable in the system encoding codepage
(e.g. japanese file names copied to european computers). These will
only work using wchar_t.

Yes, this is very confusing.

HTH
R'

Ralf Fassel

unread,
May 21, 2019, 10:04:51 AM5/21/19
to
* Alexandru <alexandr...@meshparts.de>
| Here is the function:
| https://www.meshparts.de/download/software/checksum.c
>
| The interesting part is in FileContentChecksum_Cmd

Please also note that the above file also holds an answer for your
original question:

From: Alexandru <alexandr...@meshparts.de>
Subject: Passing file path with ß to C function from DLL
Newsgroups: comp.lang.tcl
Date: Wed, 15 May 2019 02:03:38 -0700 (PDT)

--<snip-snip>--
Everything works fine except when the file name contains "ß" and I
suppose any other special chars. I suspect an issue with the char
encoding, but I have no I idea how to solve it.

Interestingly, I don't get an error. I just get the same checksum
"D41D8CD98F00B204E9800998ECF8427E" as a result, no matter what the
file content is.

In the checksum.c I bet you *do* get an error with the fopen(), but you
just print it and then you're calculating the checksum anyway if fopen()
fails.

fd = fopen(FileName,"rb");
if(fd==NULL){
fprintf(stderr, "md5sum: can't open %s\n", FileName);
}
sum(fd, FileName, checksum);
fclose(fd);

If fopen() fails, this will always lead to the same sum, since the
following fread() will immediately fail too (if you're lucky, I'm not
sure whether calling fread() with a NULL stream pointer is defined
behaviour), and then you're checksumming an buffer of length zero.
There are some other missing checks of return values, too (e.g. md5() in
sum() can return 'nil', too, which should be handled).

IMHO at least you should make FileContentChecksum() and sum() return an
indication of success (e.g. int 0/1) instead of void, and raise an
TCL_ERROR in FileContentChecksum_Cmd() if anything goes wrong.

HTH
R'

Harald Oehlmann

unread,
May 21, 2019, 11:41:25 AM5/21/19
to
Dear Ralph,

thank you for all this information. I have read the man-page of
Tcl_FSGetNativePath - Impressive page and impressive function.

So, there is an object type of path and this object has the native
representation as 2nd value beside the path as string.
Also, there is no possibility to fail for the function.

I may add a wiki page soon for this function including your snipped plus
the header stuff forcing unicode API, so TCHAR is for sure wchar_t.:

#define _UNICODE
#include <Windows.h>
#include tcl.h

Thank you,
Harald

Ralf Fassel

unread,
May 21, 2019, 12:34:26 PM5/21/19
to
* Harald Oehlmann <wort...@yahoo.de>
| [Tcl_FSGetNativePath] - Impressive page and impressive function.
>
| So, there is an object type of path and this object has the native
| representation as 2nd value beside the path as string.
| Also, there is no possibility to fail for the function.

While the manpage does not document it, looking at the TCL source code
there are some code paths that return NULL, so one should check the
returned value.

| I may add a wiki page soon for this function including your snipped plus
| the header stuff forcing unicode API, so TCHAR is for sure wchar_t.:
>
| #define _UNICODE
| #include <Windows.h>
| #include tcl.h

I have to admit that I'm a bit confused here, too.

TCL 8.6 itself #defines *both* "UNICODE" and "_UNICODE" in the Makefiles
on Windows (win/Makefile.in, win/rules.vc).

So the TCL 8.6 library usually has UNICODE *and* _UNICODE defined via
the compiler command line flags when compiling TCL (not via tcl.h and
derived, these only check the setting).

If I now compile a C extension without UNICODE defined, then I would
expect a return-value-mismatch between the actual value returned by TCL
library function (which was compiled with UNICODE defined) and my
extension (which uses the valie with UNICODE not defined).
The TCHAR macro resolves to different types in these two cases.

(cf tcl8.6.9/generic/tclPlatDecls.h
/*
* TCHAR is needed here for win32, so if it is not defined yet do it here.
* This way, we don't need to include <tchar.h> just for one define.
*/
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(_TCHAR_DEFINED)
# if defined(_UNICODE)
typedef wchar_t TCHAR;
# else
typedef char TCHAR;
# endif
# define _TCHAR_DEFINED
#endif

)

Maybe someone with more experience on this can add some insight here...

R'

Alexandru

unread,
May 21, 2019, 3:21:00 PM5/21/19
to
Am Dienstag, 21. Mai 2019 12:26:37 UTC+2 schrieb Ralf Fassel:

> If you instead call
>
> wchar_t* fname = Tcl_FSGetNativePath(objv[1])
> ...
> _wfopen(fname, ...)
>
> https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2019
>

Thank you Ralf for the very valuable help. I implemented the changed as you advice but somehow I stil get the same result and in addition a warning:

warning: passing argument 2 of '_wfopen' from incompatible pointer type [-Wincompatible-pointer-types]
fd = _wfopen(FileName,"rb, ccs=UNICODE");

The examples from the link you provided look the same so I don't understand the warning. I also tried all tree possible encodings but the result is always the same.

Here are the adapted functions:

void FileContentChecksum(const wchar_t* FileName, char* checksum) {

int c;
FILE *fd;

// fd = fopen(FileName,"rb");

fd = _wfopen(FileName,"rb, ccs=UTF-8");

if (fd==NULL) {
fprintf(stderr, "md5sum: can't open %s\n", FileName);
}
sum(fd, checksum);
fclose(fd);

}

static int
FileContentChecksum_Cmd (ClientData cdata, Tcl_Interp *ip, int objc, Tcl_Obj *const objv[]) {
// objv[1] filename

Tcl_Obj *obj;
// char* filename;
unsigned char checksum[32];


// Extract the double value from it.
// filename = Tcl_GetString(objv[1]);
const wchar_t* filename = Tcl_FSGetNativePath(objv[1]);

FileContentChecksum(filename,checksum);
obj = Tcl_NewStringObj(checksum,32);
Tcl_SetObjResult(ip, obj);

return TCL_OK;
}

Harald Oehlmann

unread,
May 21, 2019, 4:08:42 PM5/21/19
to
Hi Ralf,

it is for an own typically stubs-enabled extension. The standard
Makefiles may be used, but this is not mandatory.

I personally have a couple of one file C extensions which end-up in
DLL's. I compile them within the IDE of MS-VC6++ or MS-VS2012. And I
define all critical defines in the file, so I can not forget them in the
properties of MS-VC.

And "_UNICODE" is critical to change TCHAR to wchar_t.
The 2nd critical one is "USE_TCL_STUBS".

Here is the wiki contribution, untested but all of my knowledge...

https://wiki.tcl-lang.org/page/Tcl%5FFSGetNativePath?V=1

Anybody is invited to edit it directly.

Thanks,
Harald

Ralf Fassel

unread,
May 22, 2019, 3:53:15 AM5/22/19
to
* Harald Oehlmann <wort...@yahoo.de>
| Here is the wiki contribution, untested but all of my knowledge...
>
| https://wiki.tcl-lang.org/page/Tcl%5FFSGetNativePath?V=1

I have corrected a tiny bit: _wfopen() expects all wchar_t arguments,
so you need _wfopen(..., L"rb") instead of plain "rb".

I will try that code out later...

R'

Ralf Fassel

unread,
May 22, 2019, 3:55:41 AM5/22/19
to
* Alexandru <alexandr...@meshparts.de>
| Am Dienstag, 21. Mai 2019 12:26:37 UTC+2 schrieb Ralf Fassel:
>
| > If you instead call
| >
| > wchar_t* fname = Tcl_FSGetNativePath(objv[1])
| > ...
| > _wfopen(fname, ...)
| >
| > https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2019
| >
>
| Thank you Ralf for the very valuable help. I implemented the changed
| as you advice but somehow I stil get the same result and in addition a
| warning:
>
| warning: passing argument 2 of '_wfopen' from incompatible pointer type [-Wincompatible-pointer-types]
| fd = _wfopen(FileName,"rb, ccs=UNICODE");

You need

_wfopen(FileName, L"rb, ccs=UNICODE")
^

(note the 'L' before the string constant).
_wfopen() expects all arguments being wchar_t's, the 'L' makes the
string constant one.

HTH
R'

Harald Oehlmann

unread,
May 22, 2019, 4:14:37 AM5/22/19
to
Ok, thank you ! I thought, the "ccs=UNICODE" is for the contents, not
for the file path specification.

THanks,
Harald

Ralf Fassel

unread,
May 22, 2019, 4:25:08 AM5/22/19
to
* Harald Oehlmann <wort...@yahoo.de>
| > You need
| >
| > _wfopen(FileName, L"rb, ccs=UNICODE")
| > ^
| >
| > (note the 'L' before the string constant).
| > _wfopen() expects all arguments being wchar_t's, the 'L' makes the
| > string constant one.
>
| Ok, thank you ! I thought, the "ccs=UNICODE" is for the contents, not
| for the file path specification.

It is indeed for the *contents* of the file!

The 'L' is just to make the string "rb, ccs=UNICODE" a wchar_t* string
instead of a char* string, so it fits the function signature of

_wfopen(wchar_t*, wchar_t*).

If you code
_wfopen(FileName, "rb, ccs=UNICODE")
without the 'L', you would call a

_wfopen(wchar_t*, char*)

instead (note the difference in the type of the second argument).

R'

Harald Oehlmann

unread,
May 22, 2019, 4:48:35 AM5/22/19
to
Thank you ! The "L" is totally ok. But the "ccs=UNICODE" is not required
to access the file contents as binary bytes (and not as UNICODE).

Thank you,
Harald

Alexandru

unread,
May 22, 2019, 8:37:05 AM5/22/19
to
That was the last missing key information! Thank you! Now it works like a charm.
Cheers
Alex

Harald Oehlmann

unread,
May 22, 2019, 8:48:49 AM5/22/19
to
This is a good day! Ralf gets a beer in Nürnberg ;-)
Could you update the wiki page with your final observings ? Perhaps
including compilation parameters etc.

Thanks,
Harald

Alexandru

unread,
Jun 5, 2019, 1:50:40 AM6/5/19
to
On a Windows 7 system the checksum function crashes on simple files without special chars in the path. The app simply closes and the OS shows the "app crashed" window.

Before changing the way the path is send to C, the function worked.

On Win 10 there is not problem.

What could be the reason?

Alexandru

unread,
Jun 5, 2019, 4:16:03 AM6/5/19
to
Nope, the issue is caused by the way I compile the dll. Recently I changed my machine and I'm sing mingw 64 bit. In the past I used mingw 32 bit. I don't find this intallation anymore. It might also be that the Win 7 is 32 bit and I compile on Win 10 64 bit. I'll try to compile on Win 7 32 bit...

Alexandru

unread,
Jun 5, 2019, 4:33:28 AM6/5/19
to
I must correct again: Both systems are 64 bit, the difference is win 7 to win 10. Somehow I must compile on win 7 in order to get a working dll for win 7. Seems to be a incompatibility of win 7 with mingw compilations that are done on win 10. No idea why...

Rich

unread,
Jun 5, 2019, 7:48:35 AM6/5/19
to
The cynical among us would say it is an intentional break on MS's part
to encourage migration away from W7 to W10. Once you go W10, there's
no going back for you.

Reality is that it is likely something new for W10 that mingw is
utilizing that did not exist on W7, so when you compile on W7 mingw
uses the older function/library that exists on both, but when you
compile on W10 it uses the newer function/library that is W10 only.

Does mingw have a command line switch to set a "windows version maximum
target" (something similar to the CPU architecture target switches).
If it does, then giving that switch, with the "windows 7 max" option
(should it exist) might create a dll on W10 that works on W7.

Robert Heller

unread,
Jun 5, 2019, 7:56:19 AM6/5/19
to
At Wed, 5 Jun 2019 01:33:25 -0700 (PDT) Alexandru <alexandr...@meshparts.de> wrote:

>
> Am Mittwoch, 5. Juni 2019 10:16:03 UTC+2 schrieb Alexandru:
> > Am Mittwoch, 5. Juni 2019 07:50:40 UTC+2 schrieb Alexandru:
> > > Am Mittwoch, 22. Mai 2019 10:25:08 UTC+2 schrieb Ralf Fassel:
> > > > * Harald Oehlmann <wort...@yahoo.de>
> > > > | > You need
> > > > | >=20
> > > > | > _wfopen(FileName, L"rb, ccs=3DUNICODE")
> > > > | > ^
> > > > | > =20
> > > > | > (note the 'L' before the string constant).
> > > > | > _wfopen() expects all arguments being wchar_t's, the 'L' makes th=
> e
> > > > | > string constant one.
> > > > >
> > > > | Ok, thank you ! I thought, the "ccs=3DUNICODE" is for the contents,=
> not
> > > > | for the file path specification.
> > > >=20
> > > > It is indeed for the *contents* of the file!
> > > >=20
> > > > The 'L' is just to make the string "rb, ccs=3DUNICODE" a wchar_t* str=
> ing
> > > > instead of a char* string, so it fits the function signature of
> > > >=20
> > > > _wfopen(wchar_t*, wchar_t*).
> > > >=20
> > > > If you code
> > > > _wfopen(FileName, "rb, ccs=3DUNICODE")
> > > > without the 'L', you would call a
> > > >=20
> > > > _wfopen(wchar_t*, char*)
> > > >=20
> > > > instead (note the difference in the type of the second argument).
> > > >=20
> > > > R'
> > >=20
> > > On a Windows 7 system the checksum function crashes on simple files wit=
> hout special chars in the path. The app simply closes and the OS shows the =
> "app crashed" window.=20
> > >=20
> > > Before changing the way the path is send to C, the function worked.=20
> > >=20
> > > On Win 10 there is not problem.
> > >=20
> > > What could be the reason?
> >=20
> > Nope, the issue is caused by the way I compile the dll. Recently I change=
> d my machine and I'm sing mingw 64 bit. In the past I used mingw 32 bit. I =
> don't find this intallation anymore. It might also be that the Win 7 is 32 =
> bit and I compile on Win 10 64 bit. I'll try to compile on Win 7 32 bit...
>
> I must correct again: Both systems are 64 bit, the difference is win 7 to w=
> in 10. Somehow I must compile on win 7 in order to get a working dll for wi=
> n 7. Seems to be a incompatibility of win 7 with mingw compilations that ar=
> e done on win 10. No idea why...

This is SOP: *always* compile on the lowest version of the O/S you intend to
support. Virtually *ALL* system software (including O/S supplied shared
libraries/DLLs) is downward compatible: that is code compliled against version
X will run with version X+1, but [probably] won't run with version X-1.

There will likely to be cases where you need to compile both places -- usually
when the new version of the O/S completely replaces library foo will library
bar so code compiled against library foo won't run on the new system, but this
generally does not happen (usually the O/S will include a "legacy" library foo
to support older program).

>

--
Robert Heller -- 978-544-6933
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

Alexandru

unread,
Jun 5, 2019, 8:05:24 AM6/5/19
to
I don't know about the switch but it's worth to search for it. I'll see if I can find something.

Alexandru

unread,
Jun 5, 2019, 8:07:47 AM6/5/19
to
Am Mittwoch, 5. Juni 2019 13:56:19 UTC+2 schrieb Robert Heller:
> This is SOP: *always* compile on the lowest version of the O/S you intend to
> support. Virtually *ALL* system software (including O/S supplied shared
> libraries/DLLs) is downward compatible: that is code compliled against version
> X will run with version X+1, but [probably] won't run with version X-1.
>
> There will likely to be cases where you need to compile both places -- usually
> when the new version of the O/S completely replaces library foo will library
> bar so code compiled against library foo won't run on the new system, but this
> generally does not happen (usually the O/S will include a "legacy" library foo
> to support older program).

Thanks for the clarification. Took a while to learn this...
0 new messages