Mike Rosing
Mike Rosing

Reputation: 35

XOpenDisplay fortran fails but C works fine

I found an Xlib interface to Fortran here. When I run a simple C code (creating X windows) all is well. But the simplest Fortran code fails.

     program simple
      use xlib

      type(c_ptr) display

      display = x_open_display_test('')       <----------------infinite loop
!      display = x_open_display('')       <---------------- returns NULL
      if(.not. c_associated(display)) then
         write(6, 901)
         stop
      end if
   901     format('Display is NULL?')
      end program simple

I modified the interface in Xlib.f90 to try to debug things, and things went to hell at the speed of light:

:
    public :: x_open_display
:
   interface
:
        ! Display *XOpenDisplay (char *display_name)
        function x_open_display(display_name) bind(c, name='XOpenDisplay')
            import :: c_char, c_ptr
            implicit none
            character(kind=c_char), intent(in) :: display_name
            type(c_ptr)                        :: x_open_display
        end function x_open_display
:
   end interface
:
    function x_open_display_test(display_name) bind(c, name='XOpenDisplay')
      character(kind=c_char), intent(in) :: display_name
      type(c_ptr)                        :: x_open_display_test
      x_open_display_test = x_open_display(display_name)
      write (6, 95)
95    format('xopen')
    end function x_open_display_test

Instead of just failing, I got 15,000 some lines of "xopen" and a seg fault.

If I call x_open_display('') the program gets a NULL response. In C the same thing works fine. Adding something to the module causes an infinite loop. Obviously I'm doing something stupid, but I can't see it.

How do I get Fortran to see the same thing C operates with?

The reason for all this is to port 50 year old "dusty deck" code to work under modern Linux. The I/O is all I want to mess with. 50 years of debugging I do not want to touch!

Upvotes: 3

Views: 86

Answers (1)

PierU
PierU

Reputation: 2688

I don't know if it's the only reason, but in contrast to C:

  • Fortran strings are not terminated by a null character
  • the length of the string is passed in a hidden argument in function calls, and the function on the C side is not aware of this argument.

I would modify the interface like this:

interface
    ! Display *XOpenDisplay (char *display_name)
    function x_open_display(display_name) bind(c, name='XOpenDisplay')
        import :: c_char, c_ptr
        implicit none
        character(kind=c_char,len=1), intent(in) :: display_name(*)
        type(c_ptr) :: x_open_display
    end function x_open_display
end interface

And I would call the function like this:

display = x_open_display(''//c_null_char)

Upvotes: 3

Related Questions