Version 0 of Tcl_FSGetNativePath

Updated 2019-05-21 19:51:39 by oehhar

TCL Library command to get a native path.

TCL 8.6.9 man page: [L1 ]

Error case

HaO2019-05-21: There is no official error case. Nevertheless, Ralf Fassel states on clt 2019-05-21 "Re: Passing file path with ß to C function from DLL":

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.

Windows DLL example

HaO2019-05-21: Adapted from Ralf Fassel on clt 2019-05-21 "Re: Passing file path with ß to C function from DLL", question by Alexandru Dadalau.

A C function should hash a file. The file path is specified from TCL. Platform is Windows. Here is a skeleton:

// the following defines are important and should normally be given in the make file.
// To be sure that they are not forgotten, they are given here, accepting an eventual error of redefinition
#define USE_TCL_STUBS
#define UNICODE
#define _UNICODE
#define DLL_BUILD
#include <Windows.h>
#include <tchar.h>
#include "tcl.h"
int HashCmd(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    wchar_t* fname;
    FILE * hFile;
    int hashValue;
    if (objc <= 1) {
        Tcl_WrongNumArgs(interp, 1, objv, "path");
        return TCL_ERROR;
    }
    fname = Tcl_FSGetNativePath(objv[1]);
    if ( NULL == fname || NULL == (hFile = _wfopen(fname, "rb"))) {
        Tcl_SetStringObj( Tcl_GetObjResult(interp), "Wrong file path",-1);
        return TCL_ERROR;
    }
    // do the hashing here into variable hashValueby reading from file handler hFile
    fclose(hFile);
    // return the result here
    Tcl_SetIntObj( Tcl_GetObjResult(interp), hashValue);
    return TCL_OK;
}

BOOL __declspec(dllexport) WINAPI DllEntryPoint(HINSTANCE hInstance, DWORD seginfo, LPVOID lpCmdLine)
{
  return TRUE;
}
int __declspec(dllexport) Winprint_Init (Tcl_Interp *Interp)
{
        if (Tcl_InitStubs(Interp, "8.1", 0) == NULL)
                return TCL_ERROR;
        Tcl_CreateObjCommand(Interp, "hash", HashCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
        Tcl_PkgProvide (Interp, "hash", "1.0");
        return TCL_OK;
}