* 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 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
* 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
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