HDFGroup / HDF.PInvoke

Raw HDF5 Power for .NET
http://www.hdfgroup.org/HDF5
Other
80 stars 29 forks source link

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

Open SBahre opened 5 years ago

SBahre commented 5 years ago

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.

gheber commented 5 years ago

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().

hyabean commented 5 years ago

@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|

JanWosnitza commented 5 years ago

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.