Bug with ISO_C_BINDING on Mac OS?

Tobias Burnus burnus@net-b.de
Sat Jun 1 13:14:00 GMT 2013


Am 01.06.2013 14:48, schrieb Angelo Graziosi:
> I apologize if I introduce myself in this topic, I have tried the 
> original test cases proposed by Janus and they work on Cygwin (32 bit) 
> and fail on Mac OS X (64 bit, Lion) as described.. but what caught my 
> attention is the above sentence... I have created a module which 
> interface several Windows API etc. functions,
>
> ...
>   public BeginPaint
>   interface
>      function BeginPaint(hWnd,lpPaint) bind(C,name='BeginPaint')
>        import
>        !GCC$ ATTRIBUTES STDCALL :: BeginPaint
>        integer(HDC_T) :: BeginPaint
>        integer(HWND_T), intent(in), value :: hWnd
>        type(PAINTSTRUCT_T), intent(out) :: lpPaint
>      end function BeginPaint
>   end interface
>
> etc. At the moment the applications I have created, and compiled on XP 
> 32, run also on Windows 7 64. I wonder if I have to remove the "value" 
> attribute for the same reasons cited by Tobias..

I think your interface looks fine.

The function result is a pointer, but one can also store it in an 
integer, which is sensible as it kind of matches the Windows code which 
calls it "handle". Thus, "integer(HDC_T)" should be fine, assuming that 
HDC_T == C_intptr_t (i.e. 32 bit on Win32 and 64bit on Win64).

Similarly, hWND is under the hood a pointer - but using an integer 
instead is also fine. I again believe that you have HWND_T == C_intptr_t 
such that it is 64 bit on Win64 and 32bit in Win32. Here, the VALUE is 
required as you want to pass the handle - and not the pointer to the handle.

By contrast, for type(PAINTSTRUCT_T) you don't want to pass the struct - 
but a pointer to the struct. Thus, your usage seems to be fine.


Disclaimer: That's what I quickly gathered from looking at MSDN (see 
below). I might well have missed some fine print or might have made some 
stupid mistake.


Note: One can only really talk about the correct interface if one sees 
the full definition/declaration - both of the C code and the Fortran 
code. In addition, there are different choices possible, e.g. 
integer(c_intptr_t) and type(c_ptr) - one just has to use them consistently.

In any case, one has to be careful whether VALUE or not should be passed 
- and about integer sizes as the size of "long" (esp. Windows vs. Linux) 
and of integers storing pointers (esp. 32 vs 64 bit) differs between 
systems. (Finally, one needs to be careful with multi-dimensional arrays 
- and with LOGICAL, except one uses logical(c_bool) together with 
_Bool/boolean/bool.)

Tobias

PS: Side note, on MSDN, I found the following definitions:

HDC BeginPaint(
   _In_   HWND hwnd,
   _Out_  LPPAINTSTRUCT lpPaint
);


with:

typedef PVOID HANDLE;|
typedef HANDLE HDC;|
typedef HANDLE HWND;

and "lpPaint -Pointer to the PAINTSTRUCT".



More information about the Fortran mailing list