HDF.PInvoke icon indicating copy to clipboard operation
HDF.PInvoke copied to clipboard

Error changing the file stream for HDF5 error function H5E.print

Open SBahre opened this issue 6 years ago • 3 comments

When a HDF5 function fails it generates the error and itself prints the error in console in an console application. In another case, you can mute the automatic error printing from the stack using H5E.set_auto() and then print the message explicitly using H5E.print. Full documentation available here.

herr_t H5Eprint( hid_t estack_id, FILE * stream) )

For C#, this syntax is

int H5E.print( Int64 estack_id, Intptr stream) )

I want to redirect this error message from console to a .txt file. I am getting AccessViolation exception when I am using

string filePath = @"d:\errors.txt";
errorFileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
errorFileHandle = errorFileStream.SafeFileHandle.DangerousGetHandle();
H5E.print(estack_id, errorFileHandle)

How to get rid of this exception? Am I going correct?

I am using HDF.PInvoke version 1.10.0.4 in C# in Visual Studio 2015.

SBahre avatar Sep 25 '18 07:09 SBahre

Have you tried to create/open the file with a SafeFileHandle from the FILE* of a P/Invoked C fopen? I'm not sure if that's equivalent to errorFileStream.SafeFileHandle.DangerousGetHandle().

gheber avatar Sep 28 '18 18:09 gheber

@SBahre you can call H5E.walk instead of H5E.print.

    private static void DisableErrorPrinting()
    {
        var stackid = H5E.get_current_stack();
        H5E.auto_t auto_cb = ErrorDelegateMethod;
        H5E.set_auto(H5E.DEFAULT, auto_cb, IntPtr.Zero);

        try
        {
            hid_t fid = H5F.create(@"D:/CME.CL1812.h5",H5F.ACC_CREAT);

            hsize_t[] dims = { 256 };

            hid_t space = H5S.create_simple(1, dims, null);
            var dset = H5D.create(fid, "test1",
                H5T.FORTRAN_S1, space);

            H5D.close(dset);
            Hdf5.CloseFile(fid);

            logger.Info("fileId: {0}", fid);
            Console.ReadKey();
        }
        catch(Exception ex)
        {
            logger.Error(ex, "");
        }
    }

    private static int custom_print_cb1(uint n, ref H5E.error_t err_desc, IntPtr client_data)
    {
        logger.Info("custom_print_cb1: {0}, {1}, {2}, {3}, {4}", n, err_desc.file_name, err_desc.line, err_desc.desc, err_desc.func_name);
        return 0;
    }

    private static int ErrorDelegateMethod(long estack, IntPtr client_data)
    {
        H5E.walk(H5E.DEFAULT, H5E.direction_t.H5E_WALK_UPWARD, custom_print_cb1, IntPtr.Zero);

        return -1;
    }

log file: 2019-01-21 18:47:43.8019|INFO|ReadFromRedisToHDF5.Program|1|custom_print_cb1: 0, D:\build\HDF5\1.10.4\hdf5-1.10.4\src\H5F.c, 417, invalid flags, H5Fcreate| 2019-01-21 18:47:43.8019|INFO|ReadFromRedisToHDF5.Program|1|custom_print_cb1: 0, D:\build\HDF5\1.10.4\hdf5-1.10.4\src\H5Gloc.c, 246, invalid object ID, H5G_loc| 2019-01-21 18:47:43.8019|INFO|ReadFromRedisToHDF5.Program|1|custom_print_cb1: 1, D:\build\HDF5\1.10.4\hdf5-1.10.4\src\H5D.c, 119, not a location ID, H5Dcreate2| 2019-01-21 18:47:43.8019|INFO|ReadFromRedisToHDF5.Program|1|custom_print_cb1: 0, D:\build\HDF5\1.10.4\hdf5-1.10.4\src\H5D.c, 331, not a dataset, H5Dclose| 2019-01-21 18:47:43.8019|INFO|ReadFromRedisToHDF5.Program|1|custom_print_cb1: 0, D:\build\HDF5\1.10.4\hdf5-1.10.4\src\H5F.c, 664, not a file ID, H5Fclose|

hyabean avatar Jan 21 '19 10:01 hyabean

Hi @SBahre, IntPtr can be a lot of things e.g. a void pointer or an integer. In case of SafeHandle.DangerousGetHandle it's a windows handle like the one returned from OpenFile. That's something very different from what H5Eprint expects.

Both solutions from @gheber and @jhy871167495 seem to be a viable paths.

JanWosnitza avatar Jan 23 '19 13:01 JanWosnitza