comp.lang.ada
 help / color / mirror / Atom feed
* .h header file in ObjectAda 8.2.2 source code?
@ 2013-07-19 11:47 dd24fan
  2013-07-19 13:02 ` Niklas Holsti
  2013-07-19 15:36 ` dd24fan
  0 siblings, 2 replies; 11+ messages in thread
From: dd24fan @ 2013-07-19 11:47 UTC (permalink / raw)


Hi, all! I currently have this requirement to include a .h file in the ObjectAda source code.  I'm not quite sure how to do this.

Is this done by pragmas?  Btw, in my source code now I've referenced all the functions needed to communicate with the hardware via pragma imports.  I've also included the .lib file the vendor suggests in my project.

When i try to run the executable in my test environment the .exe just hangs.  Any insight would be greatly appreciated.

D

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-19 11:47 .h header file in ObjectAda 8.2.2 source code? dd24fan
@ 2013-07-19 13:02 ` Niklas Holsti
  2013-07-19 15:36 ` dd24fan
  1 sibling, 0 replies; 11+ messages in thread
From: Niklas Holsti @ 2013-07-19 13:02 UTC (permalink / raw)


On 13-07-19 14:47 , dd24fan wrote:
> Hi, all! I currently have this requirement to include a .h file in
> the ObjectAda source code.  I'm not quite sure how to do this.

That depends on what the .h file contains... in C, it can contain any
kind of C code. I've seen C programs in which the .h files contain large
chunks of executable code, both in macros and in real functions.
(Perhaps that C programmer thought that only .h files can be #included.)

> Is this done by pragmas?

Yes, for some .h information. Other information, such as type
declarations, must be translated into ordinary Ada code (Ada type
declarations), i.e. not (only) pragmas.

Can you show us the .h file, or some of the parts of it that you are using?

> Btw, in my source code now I've referenced
> all the functions needed to communicate with the hardware via pragma
> imports.

That is the right way, for functions that are declared in the .h file
and then called from the Ada code. Note that in addition to the Import
pragmas for the functions, the parameter types may need Convention
pragmas to make the Ada compiler follow C memory structures.

Can you show an example of a C function declared in the .h file, and
your corresponding Ada function (declaration)?

> I've also included the .lib file the vendor suggests in my
> project.

Sounds like a necessary thing, although I don't know the details of how
C libraries are included in ObjectAda programs.

> When i try to run the executable in my test environment the .exe just
> hangs.  Any insight would be greatly appreciated.

Not enough information... Where does it hang? Is any part of the Ada
main subprogram executed? Does it hang in the first call to the C code?

You speak of "communicating with hardware". Are special drivers
involved? Does the C code use interrupts? Does the program run on a
PC/Windows/Linux, or on an embedded bare-board system? Can you step
through the code with a debugger?

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-19 11:47 .h header file in ObjectAda 8.2.2 source code? dd24fan
  2013-07-19 13:02 ` Niklas Holsti
@ 2013-07-19 15:36 ` dd24fan
  2013-07-20  5:41   ` Randy Brukardt
  2013-07-20  8:07   ` Niklas Holsti
  1 sibling, 2 replies; 11+ messages in thread
From: dd24fan @ 2013-07-19 15:36 UTC (permalink / raw)


Okay, the header file file contains all necessary information to access type definitions and RTL function prototypes. Below is a snippet of the .h file:

=============
.
.
.
/* Windows Declarations */
#ifdef WIN32
#include <windows.h>
#define _DECL	WINAPI
#define _EXTERN

/* Non Windows Declarations */
#else
#define _DECL
#define _EXTERN

#ifdef _MSC_VER
#define getvect _dos_getvect
#define setvect _dos_setvect
#define disable _disable
#define enable  _enable
#endif

#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* RTL is written in 'C' */
#ifdef __cplusplus
extern "C" {
#endif

.
.
.
#define (this section just defines different constants)
.
.
.
/* Include all RTL header files necessary for external compiles */
.
.
.
#include "xyz.h" (this section has 40+ #includes of .h files)
.
.
.
#ifdef __cplusplus
}
#endif

#endif

============

The program runs on a PC Windows environment.  It does not hang in the ada main subprogram execution.

I believe it to hang in the first call to the C code.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-19 15:36 ` dd24fan
@ 2013-07-20  5:41   ` Randy Brukardt
  2013-07-22 19:06     ` dd24fan
                       ` (2 more replies)
  2013-07-20  8:07   ` Niklas Holsti
  1 sibling, 3 replies; 11+ messages in thread
From: Randy Brukardt @ 2013-07-20  5:41 UTC (permalink / raw)


"dd24fan" <d3v3r4@gmail.com> wrote in message 
news:b42127a4-c5dc-4fd0-86cd-dd63f014897b@googlegroups.com...
...
> The program runs on a PC Windows environment.  It does not hang in the ada 
> main subprogram execution.
>
> I believe it to hang in the first call to the C code.

Typically, that means that there is a mistake in the specifications of the 
functions that are imported with pragma Import. As to finding the actual 
problem, usually all you can do it step through the bad call with a debugger 
and see what it is doinng wrong (sometimes you have to compare it to a call 
from C that works).

The problem with interfacing to a foreign language is that the Ada compiler 
is helpless to provide you much if any help. Only the most gross errors can 
be detected, because the Ada compiler doesn't know anything about the C code 
other than what you tell it, and if you tell it the wrong thing...

When we wer building Claw, we spent a *lot* of time debugging botched 
Imports, and we never really found a shortcut (other than triple-checking 
the imported function declarations before cracking out the debugger, 
probably half the time, the problem became evident).

Humm, you mentioned that this is on Windows. Do you know if these are 
C-convention or Stdcall-convention functions? Use the wrong one, and nothing 
will work. (Win32 is Stdcall, for instance, *not* C). For Stdcall, you need 
to get the number of parameters the same as C expects, or you will have 
problems (although those usually are an inability to link).

                          Randy.




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-19 15:36 ` dd24fan
  2013-07-20  5:41   ` Randy Brukardt
@ 2013-07-20  8:07   ` Niklas Holsti
  2013-08-01 15:03     ` Stephen Leake
  1 sibling, 1 reply; 11+ messages in thread
From: Niklas Holsti @ 2013-07-20  8:07 UTC (permalink / raw)


On 13-07-19 18:36 , dd24fan wrote:
> Okay, the header file file contains all necessary information
> to access type definitions and RTL function prototypes.

Oh, "RTL"... Is the C library some kind of "run-time library" for some
model-based design tool? If so, does the library involve or implement
multi-threading or some other kind of concurrency? That could cause
conflicts with the Ada run-time system.

> Below is a snippet of the .h file:

   [ elided ]

Looks like a nicely structured C header, which in Ada can be represented
by Ada constant, type, and subprogram declarations with pragma
Convention and Import.

> #include "xyz.h" (this section has 40+ #includes of .h files)

Ouch... lots of work, if you need all 40+ headers. The GNU Ada compiler
system has a mode where the compiler can translate a C header file into
Ada declarations -- perhaps this could help do the bulk work.

> I believe it to hang in the first call to the C code.

Randy's advice is good.

Also, check that you have initialized the library correctly --
typically, the application code has to make some initialization calls,
before doing any other calls, and omitting the initialization can cause
havoc or hang.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-20  5:41   ` Randy Brukardt
@ 2013-07-22 19:06     ` dd24fan
  2013-07-22 19:08     ` dd24fan
  2013-07-22 19:50     ` dd24fan
  2 siblings, 0 replies; 11+ messages in thread
From: dd24fan @ 2013-07-22 19:06 UTC (permalink / raw)


Thanks for the insight. My latest debugging efforts have pointed me to the Initialization of the device.  I do have a compare of what the C code is doing because the vendor has software in a analyzer/simulator that i was able to run.

Here is the snippet of the C code:

==============
.
.
.
    S16BIT    s16Result = 0x0000;
    S16BIT    s16DevNum = LOGICAL_DEVICE_NUMBER;
.
.
    /* Initialize device */
    s16Result = Initialize(s16DevNum, ACCESS_CARD, MODE, 0, 0, 0);
.
.
==============
ACCESS_CARD is defined as 16BIT
MODE is U16BIT
The last 3 parameters are defined U32BIT

so in my latest ada code i have this:
==============
.
.
   function Initialize (DevNum : S16Bit_Type;
                            wAccess: S16Bit_Type;   
                            Mode : U16Bit_Type;
                            Mem_Wrd_Size : U32Bit_Type;
                            Reg_Addr : U32Bit_Type;
                            Mem_Addr : U32Bit_Type
                            ) return S16Bit_Type;
   pragma Import (Stdcall, Initialize, "Initialize");
.
.
   procedure Open (Device_Num : in S16Bit_Type;
                   Is_Open : in out Boolean;
                   Good : out Boolean) is

      Result : S16Bit_Type;

      ACCESS_CARD : U16Bit_Type := 16#0000#;
      MODE : 16Bit_Type := 1;
.
.

   begin
      Good := False;
      
      Results := Gb.Msgbox(Text    => "procedure Open begin",
                           Caption => "procedure Open begin",
                           Style   => 4,
                           Handle  => Gb.Handle(Form));	      
      
      --    Initialize device
      
               Result := Initialize (S16Bit_Type (Device_Num),
                               ACCESS_CARD,
                               MODE,
                               16#00000000#,
                               16#00000000#,
                               16#00000000#);

         Print (Device_Num, "Initialize => ", Result);
	 
         Results := Gb.Msgbox(Text    => "Initialized?",
                                          Caption => "Initialized?",
                                          Style   => 4,
                                          Handle  => Gb.Handle(Form));	 
.
.
.
==============
Some notes: Device_Num is originally defined as an integer elsewhere in the code so I type cast it.  



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-20  5:41   ` Randy Brukardt
  2013-07-22 19:06     ` dd24fan
@ 2013-07-22 19:08     ` dd24fan
  2013-07-22 20:04       ` Niklas Holsti
  2013-07-22 19:50     ` dd24fan
  2 siblings, 1 reply; 11+ messages in thread
From: dd24fan @ 2013-07-22 19:08 UTC (permalink / raw)


Thanks for the insight. My latest debugging efforts have pointed me to the Initialization of the device.  I do have a compare of what the C code is doing because the vendor has software in a analyzer/simulator that i was able to run. 

Here is the snippet of the C code: 

============== 
. 
. 
. 
    S16BIT    s16Result = 0x0000; 
    S16BIT    s16DevNum = LOGICAL_DEVICE_NUMBER; 
. 
. 
    /* Initialize device */ 
    s16Result = Initialize(s16DevNum, ACCESS_CARD, MODE, 0, 0, 0); 
. 
. 
============== 
ACCESS_CARD is defined as 16BIT 
MODE is U16BIT 
The last 3 parameters are defined U32BIT 

so in my latest ada code i have this: 
============== 
. 
. 
   function Initialize (DevNum : S16Bit_Type; 
                            wAccess: S16Bit_Type;   
                            Mode : U16Bit_Type; 
                            Mem_Wrd_Size : U32Bit_Type; 
                            Reg_Addr : U32Bit_Type; 
                            Mem_Addr : U32Bit_Type 
                            ) return S16Bit_Type; 
   pragma Import (Stdcall, Initialize, "Initialize"); 
. 
. 
   procedure Open (Device_Num : in S16Bit_Type; 
                   Is_Open : in out Boolean; 
                   Good : out Boolean) is 

      Result : S16Bit_Type; 

      ACCESS_CARD : U16Bit_Type := 16#0000#; 
      MODE : S16Bit_Type := 1; 
. 
. 

   begin 
      Good := False; 
      
      Results := Gb.Msgbox(Text    => "procedure Open begin", 
                           Caption => "procedure Open begin", 
                           Style   => 4, 
                           Handle  => Gb.Handle(Form));               
      
      --    Initialize device 
      
               Result := Initialize (S16Bit_Type (Device_Num), 
                               ACCESS_CARD, 
                               MODE, 
                               16#00000000#, 
                               16#00000000#, 
                               16#00000000#); 

         Print (Device_Num, "Initialize => ", Result); 
         
         Results := Gb.Msgbox(Text    => "Initialized?", 
                                          Caption => "Initialized?", 
                                          Style   => 4, 
                                          Handle  => Gb.Handle(Form));         
. 
. 
. 
============== 
Some notes: Device_Num is originally defined as an integer elsewhere in the code so I type cast it.   

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-20  5:41   ` Randy Brukardt
  2013-07-22 19:06     ` dd24fan
  2013-07-22 19:08     ` dd24fan
@ 2013-07-22 19:50     ` dd24fan
  2 siblings, 0 replies; 11+ messages in thread
From: dd24fan @ 2013-07-22 19:50 UTC (permalink / raw)


Thanks for the insight. My latest debugging efforts have pointed me to the Initialization of the device.  I do have a compare of what the C code is doing because the vendor has software in a analyzer/simulator that i was able to run. 

Here is the snippet of the C code: 

============== 
. 
. 
. 
    S16BIT    s16Result = 0x0000; 
    S16BIT    s16DevNum = LOGICAL_DEVICE_NUMBER; 
. 
. 
    /* Initialize device */ 
    s16Result = Initialize(s16DevNum, ACCESS_CARD, MODE, 0, 0, 0); 
. 
. 
============== 
ACCESS_CARD is defined as S16BIT 
MODE is U16BIT 
The last 3 parameters are defined U32BIT 

so in my latest ada code i have this: 
============== 
. 
. 
   function Initialize (DevNum : S16Bit_Type; 
                            wAccess: S16Bit_Type;   
                            Mode : U16Bit_Type; 
                            Mem_Wrd_Size : U32Bit_Type; 
                            Reg_Addr : U32Bit_Type; 
                            Mem_Addr : U32Bit_Type 
                            ) return S16Bit_Type; 
   pragma Import (Stdcall, Initialize, "Initialize"); 
. 
. 
   procedure Open (Device_Num : in S16Bit_Type; 
                   Is_Open : in out Boolean; 
                   Good : out Boolean) is 

      Result : S16Bit_Type; 

      ACCESS_CARD : S16Bit_Type := 0; 
      MODE : U16Bit_Type := 16#0001#; 
. 
. 

   begin 
      Good := False; 
      
      Results := Gb.Msgbox(Text    => "procedure Open begin", 
                           Caption => "procedure Open begin", 
                           Style   => 4, 
                           Handle  => Gb.Handle(Form));               
      
      --    Initialize device 
      
               Result := Initialize (S16Bit_Type (Device_Num), 
                               ACCESS_CARD, 
                               MODE, 
                               16#00000000#, 
                               16#00000000#, 
                               16#00000000#); 

         Print (Device_Num, "Initialize => ", Result); 
          
         Results := Gb.Msgbox(Text    => "Initialized?", 
                                          Caption => "Initialized?", 
                                          Style   => 4, 
                                          Handle  => Gb.Handle(Form));         
. 
. 
. 
============== 
Some notes: Device_Num is originally defined as an integer elsewhere in the code so I type cast it.   


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-22 19:08     ` dd24fan
@ 2013-07-22 20:04       ` Niklas Holsti
  2013-07-23 12:05         ` dd24fan
  0 siblings, 1 reply; 11+ messages in thread
From: Niklas Holsti @ 2013-07-22 20:04 UTC (permalink / raw)


On 13-07-22 22:08 , dd24fan wrote:
> Thanks for the insight. My latest debugging efforts have pointed me
> to the Initialization of the device.  I do have a compare of what
> the C code is doing because the vendor has software in a
> analyzer/simulator that i was able to run. 
> 
> Here is the snippet of the C code: 
> 
> ============== 
> . 
> . 
> . 
>     S16BIT    s16Result = 0x0000; 
>     S16BIT    s16DevNum = LOGICAL_DEVICE_NUMBER; 
> . 
> . 
>     /* Initialize device */ 
>     s16Result = Initialize(s16DevNum, ACCESS_CARD, MODE, 0, 0, 0); 
> . 
> . 
> ============== 
> ACCESS_CARD is defined as 16BIT 
> MODE is U16BIT 

Are those the types of the variables ACCESS_CARD and MODE -- the actual
parameters in the Initialize call -- or the types of the corresponding
formal parameters of Initialize? In other words, how is Initialize
declared in the .h file? The actual and formal types in C are not
necessarily the same, since C converts automatically. For the Ada
declaration, you should use the formal types.

Also, what are the values of ACCESS_CARD and MODE in the C program?

> The last 3 parameters are defined U32BIT 
> 
> so in my latest ada code i have this: 
> ============== 
> . 
> . 
>    function Initialize (DevNum : S16Bit_Type; 
>                             wAccess: S16Bit_Type;   
>                             Mode : U16Bit_Type; 
>                             Mem_Wrd_Size : U32Bit_Type; 
>                             Reg_Addr : U32Bit_Type; 
>                             Mem_Addr : U32Bit_Type 
>                             ) return S16Bit_Type; 
>    pragma Import (Stdcall, Initialize, "Initialize"); 
> . 
> . 
>    procedure Open (Device_Num : in S16Bit_Type; 
>                    Is_Open : in out Boolean; 
>                    Good : out Boolean) is 
> 
>       Result : S16Bit_Type; 
> 
>       ACCESS_CARD : U16Bit_Type := 16#0000#; 
>       MODE : S16Bit_Type := 1; 

I assume that these values of ACCESS_CARD and MODE match the values used
in the C program, right?

>                Result := Initialize (S16Bit_Type (Device_Num), 
>                                ACCESS_CARD, 
>                                MODE, 
>                                16#00000000#, 
>                                16#00000000#, 
>                                16#00000000#); 

(You could as well write the three last parameters using a single "0"
for each, just as in the C code. The hexadecimal base and the multiple
zeros make no difference.)

> Some notes: Device_Num is originally defined as an integer
> elsewhere in the code so I type cast it.   

That seems unnecessary, if (as your code suggests) this Device_Num is
the parameter to the Open procedure, because that parameter is declared
as S16Bit_Type, so there is no need to convert it to S16Bit_Type in the
calls. (But it does no harm either.)

You didn't say if this Ada code still hangs. Does it?

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-22 20:04       ` Niklas Holsti
@ 2013-07-23 12:05         ` dd24fan
  0 siblings, 0 replies; 11+ messages in thread
From: dd24fan @ 2013-07-23 12:05 UTC (permalink / raw)


> Are those the types of the variables ACCESS_CARD and MODE -- the actual parameters in the Initialize call -- or the types of the corresponding formal parameters of Initialize? 
> In other words, how is Initialize declared in the .h file? The actual and formal types in C are not necessarily the same, since C converts automatically. For the Ada declaration, you should use the formal types.
> Also, what are the values of ACCESS_CARD and MODE in the C program? 

Yes, the variables are the actual parameters in the call.

in the .h the code is like this:
.
.
/* wAccess can be one of the following */ Note:(Just listing the one I need)
#define ACCESS_CARD		0		/* card running on W32 OS */ 

/* wMode parameter can be one of the following */ Note:(Just listing the one I need)
#define MODE			0x0001	/* mode */
.
.
_EXTERN S16BIT _DECL _Initialize(S16BIT DevNum, U16BIT wAccess, U16BIT wMode, U32BIT dwMemWrdSize, U32BIT dwRegAddr,	U32BIT dwMemAddr);
.
.

> I assume that these values of ACCESS_CARD and MODE match the values used in the C program, right? 

Yes, that's right.

> You didn't say if this Ada code still hangs. Does it? 

Yes, the application is still hung up.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: .h header file in ObjectAda 8.2.2 source code?
  2013-07-20  8:07   ` Niklas Holsti
@ 2013-08-01 15:03     ` Stephen Leake
  0 siblings, 0 replies; 11+ messages in thread
From: Stephen Leake @ 2013-08-01 15:03 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> On 13-07-19 18:36 , dd24fan wrote:
>> #include "xyz.h" (this section has 40+ #includes of .h files)
>
> Ouch... lots of work, if you need all 40+ headers. The GNU Ada compiler
> system has a mode where the compiler can translate a C header file into
> Ada declarations -- perhaps this could help do the bulk work.

That's 'g++ -fdump-ada-spec'; see the GNAT user guide section on
"Generating Ada Bindings for C and C++ headers"
-- 
-- Stephe

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-08-01 15:03 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-19 11:47 .h header file in ObjectAda 8.2.2 source code? dd24fan
2013-07-19 13:02 ` Niklas Holsti
2013-07-19 15:36 ` dd24fan
2013-07-20  5:41   ` Randy Brukardt
2013-07-22 19:06     ` dd24fan
2013-07-22 19:08     ` dd24fan
2013-07-22 20:04       ` Niklas Holsti
2013-07-23 12:05         ` dd24fan
2013-07-22 19:50     ` dd24fan
2013-07-20  8:07   ` Niklas Holsti
2013-08-01 15:03     ` Stephen Leake

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox