your pointer argument is being passed by reference not by value. Your current interface is equivalent to
void open_file_c(int unit, char** filename);
which is the reason it does not work. What you want is Fortran to receive the value of that pointer:
void open_file_c(int unit, char* filename);
i.e.
! Option #1: use C pointer
subroutine open_file_c(unit, filename_cptr) bind(C)
integer(c_int), intent(in), value :: unit
type(c_ptr), value :: filename_cptr
end subroutine
! Option #2: use datatype directly: your pointer is the reference to it
subroutine open_file_c2(unit, filename) bind(C)
integer(c_int), intent(in), value :: unit
character(kind=c_char), intent(in) :: filename(*)
end subroutine