comp.lang.ada
 help / color / mirror / Atom feed
* Problem creating bindings - please help
@ 2006-05-18  6:46 Gerd
  2006-05-18  7:57 ` Dmitry A. Kazakov
  2006-05-19  3:25 ` Steve
  0 siblings, 2 replies; 9+ messages in thread
From: Gerd @ 2006-05-18  6:46 UTC (permalink / raw)


Hi all,

I tried to create my own Ada bindings for a dll, but I didn't succeed.


The C-header contains:

DWORD __stdcall CAN_GetHwParam(
        HCANHW hHw,
        WORD   wParam,
        void*  pBuff,
        WORD   wBuffLen);


My Ada-spec look like this:

with System;

package CanApi2 is

pragma Linker_Options ("-lCanApi2");

subtype
  HCANHW is Integer;

subtype
  Word is Integer;

function CAN_GetHwParam (hHw : HCANHW; wParam : Word; pBuff :
System.Address; wBuffLen : Word) return Integer;

private
    pragma Import (Stdcall, CAN_GetHwParam, External_Name =>
"CAN_GetHwParam");
end CanApi2;

The lib-file (CanApi2.lib) contains this names:

 _CAN_GetHwParam@16 __imp__CAN_GetHwParam@16 _CAN_SetHwParam@12
__imp__CAN_SetHwParam@12


And that's what I get when build my test-program:

C:\Work\CAN>gnatmake cantest
gcc -c cantest.adb
gcc -c canapi2.ads
gnatbind -x cantest.ali
gnatlink cantest.ali
./cantest.o(.text+0x264):cantest.adb: undefined reference to
`CAN_GetHwParam@16'

gnatlink: cannot call C:\GNAT\bin\gcc.exe
gnatmake: *** link failed.

DLL2DEF shows this:

EXPORTS
	CAN_GetHwParam


So what's wrong with my code? Please help, thanks.

Gerd




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

* Re: Problem creating bindings - please help
  2006-05-18  6:46 Problem creating bindings - please help Gerd
@ 2006-05-18  7:57 ` Dmitry A. Kazakov
  2006-05-18 10:51   ` Gerd
  2006-05-19  3:25 ` Steve
  1 sibling, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2006-05-18  7:57 UTC (permalink / raw)


On 17 May 2006 23:46:23 -0700, Gerd wrote:

> The C-header contains:
> 
> DWORD __stdcall CAN_GetHwParam(
>         HCANHW hHw,
>         WORD   wParam,
>         void*  pBuff,
>         WORD   wBuffLen);

[...]
> function CAN_GetHwParam (hHw : HCANHW; wParam : Word; pBuff :
> System.Address; wBuffLen : Word) return Integer;
> 
> private
>     pragma Import (Stdcall, CAN_GetHwParam, External_Name =>
> "CAN_GetHwParam");

What about "_CAN_GetHwParam"? It looks like 'extern "C"' stuff.

Or maybe, pragma Import (C, CAN_GetHwParam, "CAN_GetHwParam");

BTW, is it a CAN-bus adapter APIs? Which vendor?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Problem creating bindings - please help
  2006-05-18  7:57 ` Dmitry A. Kazakov
@ 2006-05-18 10:51   ` Gerd
  2006-05-18 11:24     ` christoph.grein
  2006-05-18 12:32     ` Dmitry A. Kazakov
  0 siblings, 2 replies; 9+ messages in thread
From: Gerd @ 2006-05-18 10:51 UTC (permalink / raw)


> What about "_CAN_GetHwParam"? It looks like 'extern "C"' stuff.

The GNAT Users Guide say that the "_" and the "@16" is appended
automatically for "__stdcall" (as far as I understood). And the
function is declared as "__stdcall" in the header-file.


> BTW, is it a CAN-bus adapter APIs? Which vendor?

Yes, it is. It's a "PEAK-Service GmbH, Darmstadt" device.

Are there any CAN-bus bindings for Ada available on the net (for any
vendor)?


> What about "_CAN_GetHwParam"? It looks like 'extern "C"' stuff.
> Or maybe, pragma Import (C, CAN_GetHwParam, "CAN_GetHwParam");

Thanks, I will try it.

Gerd




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

* Re: Problem creating bindings - please help
  2006-05-18 10:51   ` Gerd
@ 2006-05-18 11:24     ` christoph.grein
  2006-05-18 12:02       ` Gerd
  2006-05-18 12:32     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 9+ messages in thread
From: christoph.grein @ 2006-05-18 11:24 UTC (permalink / raw)


Gerd wrote:
>
> The GNAT Users Guide say that the "_" and the "@16" is appended
> automatically for "__stdcall" (as far as I understood). And the
> function is declared as "__stdcall" in the header-file.

External_Name and Link_Name in pragma Import are optional. But if you
provide them, they must be exact (AFAICS).




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

* Re: Problem creating bindings - please help
  2006-05-18 11:24     ` christoph.grein
@ 2006-05-18 12:02       ` Gerd
  2006-05-18 12:15         ` Georg Bauhaus
  0 siblings, 1 reply; 9+ messages in thread
From: Gerd @ 2006-05-18 12:02 UTC (permalink / raw)



christoph.grein@eurocopter.com schrieb:

> Gerd wrote:
> >
> > The GNAT Users Guide say that the "_" and the "@16" is appended
> > automatically for "__stdcall" (as far as I understood). And the
> > function is declared as "__stdcall" in the header-file.
>
> External_Name and Link_Name in pragma Import are optional. But if you
> provide them, they must be exact (AFAICS).

No. The Users guide say the "@nn" is always added, the "_" can be
dropped by specifying a link name, but is added  if not specified in
external name.




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

* Re: Problem creating bindings - please help
  2006-05-18 12:02       ` Gerd
@ 2006-05-18 12:15         ` Georg Bauhaus
  0 siblings, 0 replies; 9+ messages in thread
From: Georg Bauhaus @ 2006-05-18 12:15 UTC (permalink / raw)


Gerd wrote:
> christoph.grein@eurocopter.com schrieb:
> 
>> Gerd wrote:
>>> The GNAT Users Guide say that the "_" and the "@16" is appended
>>> automatically for "__stdcall" (as far as I understood). And the
>>> function is declared as "__stdcall" in the header-file.
>> External_Name and Link_Name in pragma Import are optional. But if you
>> provide them, they must be exact (AFAICS).
> 
> No. The Users guide say the "@nn" is always added, the "_" can be
> dropped by specifying a link name, but is added  if not specified in
> external name.
> 

FWIW, using ObjectAda and Windows function names it's the same,
the external name of the function must be given without underscore
and @suffix.

Using gcc on Windows I get the same linker error when I try to "just"
refer to a windows function in a simple C program.



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

* Re: Problem creating bindings - please help
  2006-05-18 10:51   ` Gerd
  2006-05-18 11:24     ` christoph.grein
@ 2006-05-18 12:32     ` Dmitry A. Kazakov
  2006-05-19  8:30       ` Gerd
  1 sibling, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2006-05-18 12:32 UTC (permalink / raw)


On 18 May 2006 03:51:48 -0700, Gerd wrote:

>> BTW, is it a CAN-bus adapter APIs? Which vendor?
> 
> Yes, it is. It's a "PEAK-Service GmbH, Darmstadt" device.

I see.
 
> Are there any CAN-bus bindings for Ada available on the net (for any
> vendor)?

I don't know of any. I should not be that difficult to create one from
scratch. [ We don't use them directly, it is too many (Vector, IXXAT,
Softing, National etc), so we have an abstraction layer. ]

I am not so sure that GNAT indeed adds forwarding "_" for stdcall. At least
the error message you get indicates that linker fails to find
"CAN_GetHwParam@16", also no "_" ahead. If I correctly remember, one
"PEAK-dongle" had plain ANSI C interface, but it was a time ago. I think
that Import (C,... should work.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Problem creating bindings - please help
  2006-05-18  6:46 Problem creating bindings - please help Gerd
  2006-05-18  7:57 ` Dmitry A. Kazakov
@ 2006-05-19  3:25 ` Steve
  1 sibling, 0 replies; 9+ messages in thread
From: Steve @ 2006-05-19  3:25 UTC (permalink / raw)


"Gerd" <GerdM.O@t-online.de> wrote in message 
news:1147934783.645893.274580@u72g2000cwu.googlegroups.com...
> Hi all,
>
> I tried to create my own Ada bindings for a dll, but I didn't succeed.
>

I haven't done this with GNAT, but I have done similar work with ObjectAda. 
I have a few noted suggestions below.

>
> The C-header contains:
>
> DWORD __stdcall CAN_GetHwParam(
>        HCANHW hHw,
>        WORD   wParam,
>        void*  pBuff,
>        WORD   wBuffLen);
>
>
> My Ada-spec look like this:
>
> with System;

  with Interfaces;

>
> package CanApi2 is
>
> pragma Linker_Options ("-lCanApi2");
>
> subtype
>  HCANHW is Integer;
>

You need to look up the definition of HCANHW to find out the size.  I prefer 
to use either:

  Interfaces.Unsigned_16;
  Interfaces.Unsigned_32;
  Interfaces.Integer_16;
  Interfaces.Integer_32;

Since you are working with an interface.  Some people prefer to use types 
defined in Interfaces.C, I prefer to be more explicit for interfacing.

> subtype
>  Word is Integer;

Assuming you're working on Win32, this should be:

  subtype Word is Interfaces.Unsigned_16;

>
> function CAN_GetHwParam (hHw : HCANHW; wParam : Word; pBuff :
> System.Address; wBuffLen : Word) return Integer;
>
> private
>    pragma Import (Stdcall, CAN_GetHwParam, External_Name =>
> "CAN_GetHwParam");
> end CanApi2;
>
> The lib-file (CanApi2.lib) contains this names:
>
> _CAN_GetHwParam@16 __imp__CAN_GetHwParam@16 _CAN_SetHwParam@12
> __imp__CAN_SetHwParam@12
>
>
> And that's what I get when build my test-program:
>
> C:\Work\CAN>gnatmake cantest
> gcc -c cantest.adb
> gcc -c canapi2.ads
> gnatbind -x cantest.ali
> gnatlink cantest.ali
> ./cantest.o(.text+0x264):cantest.adb: undefined reference to
> `CAN_GetHwParam@16'
>
> gnatlink: cannot call C:\GNAT\bin\gcc.exe
> gnatmake: *** link failed.
>
> DLL2DEF shows this:
>
> EXPORTS
> CAN_GetHwParam
>
>
> So what's wrong with my code? Please help, thanks.
>
> Gerd
>

The other thing I have moved toward is loading the dll dynamically at run 
time.  If the dll is loaded automatically when the program runs, 
uncontrolled meaningless error messages (to an end user) appear and the 
program fails.  By loading dynamically I can put out a meaningful error 
message.  It is also easier to troubleshoot.

Here is an example of a few code fragments I use to set up a dynamic 
interface to adagraph.

   type PutpixelAccType is access
     function(X, Y, Hue : Integer) return Integer;
   pragma Convention( C, PutpixelAccType );

   PutpixelAcc : PutpixelAccType;

   function To_PutpixelAcc is
     new Ada.Unchecked_Conversion( WinDef.FarProc, PutpixelAccType );

   PutpixelProcName : C.Char_Array := C.To_C( "PutPixel" );

   procedure Put_Pixel (X, Y : in Integer; Hue : in Color_Type := White) is
      Return_Value : Integer;
   begin
      if PutPixelAcc /= null then
         Return_Value := PutPixelAcc(X, Y, Color_Type'Pos (Hue));
         if Return_Value < No_Errors then
            Make_Exception (Return_Value);
         end if;
      end if;
   end Put_Pixel;

-----------------------------------------------

   adagraphLibraryName : C.Char_Array := C.To_C( "adagraph.dll" );
begin
   adagraphDll := System.Null_Address;
   adagraphDll := WinBase.LoadLibrary( adagraphLibraryName(0)'access );
 ...
   PutpixelAcc := To_PutpixelAcc( WinBase.GetProcAddress( adagraphDll, 
PutpixelProcName(0)'access ) );
...

I hope this helps,

Steve
(The Duck)





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

* Re: Problem creating bindings - please help
  2006-05-18 12:32     ` Dmitry A. Kazakov
@ 2006-05-19  8:30       ` Gerd
  0 siblings, 0 replies; 9+ messages in thread
From: Gerd @ 2006-05-19  8:30 UTC (permalink / raw)


I've found the reason. It seems to be a bug in GNAT (3.15p). It depends
on the underscore "_" in the external name.
If the external function has a name xyz then everything works fine, but
if the name contains an "_" line x_z, link reports an error.

I've patched the .lib (replace "_" by "X") and the .exe (replace "X"
back to "_") and now it works. But that's not a nice method. Does
anyone know how Aonix behaves in this case (function name in dll
contains underscore)?

Gerd




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

end of thread, other threads:[~2006-05-19  8:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-18  6:46 Problem creating bindings - please help Gerd
2006-05-18  7:57 ` Dmitry A. Kazakov
2006-05-18 10:51   ` Gerd
2006-05-18 11:24     ` christoph.grein
2006-05-18 12:02       ` Gerd
2006-05-18 12:15         ` Georg Bauhaus
2006-05-18 12:32     ` Dmitry A. Kazakov
2006-05-19  8:30       ` Gerd
2006-05-19  3:25 ` Steve

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