HDF.PInvoke
HDF.PInvoke copied to clipboard
Error changing the file stream for HDF5 error function H5E.print
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.
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()
.
@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|
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.