Newbie Question - How to wrap and external Windows dll in Eiffel?

9 messages Options
Embed this post
Permalink
dciphercomputing

Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
Hi
I want to use the advantage client engine (ace) for the Advantage
Database Server which is simply a Windows dll file (ace32.dll) in an
Eiffel project.  I believe I have to create an Eiffel wrapper class with
a method for every function available in the client engine.  However, I
am not sure how this is done properly in Eiffel even after reading some
of the documentation.  So I have included a sample function here in the
hopes that someone might be able to show me the basic Eiffel class
needed to wrap this function.  There is also an ace.h file which I
assume will have to be referenced some how.
Thanks,Simon
Syntax
UNSIGNED32 AdsConnect (UNSIGNED8 *pucServerName, ADSHANDLE *phConnect);
Parameters
pucServerName (I)Full file path of the data dictionary file, server
name, or drive letter to which to connect. If the application uses a
server name as the parameter, it must include the share name for
Windows, path from the root for Linux, or volume name for Novell NetWare
as well. For example, use "\\server\share", "\\server\path_from_root",
or "\\server\volume". Linux users can also connect to the local machine
using a direct path such as "/mydata". All Advantage clients and servers
consider either slash type (forward or backslash) to be a path
delimiter, this means you could also use a connection path with forward
slashes, such as "//server/volume". Linux users should also reference
the REPLACE_UNC_SERVER section in the ads.ini documentation.
phConnect  (O)Return the connection handle if successful.
The following items are taken from the ace.h  just in case they might be
needed by anyone supplying an answer to this post.
#ifndef ADSHANDLE_DEFINED   #define ADSHANDLE_DEFINED   #if defined( x64
)      #if defined( ADS_LINUX )         // Long is 64 bits in GCC.
typedef unsigned long  ADSHANDLE;      #else         typedef unsigned
__int64  ADSHANDLE;      #endif   #else      typedef unsigned long
ADSHANDLE;   #endif#endif
UNSIGNED32 ENTRYPOINT AdsConnect( UNSIGNED8  *pucServerName,
ADSHANDLE  *phConnect );typedef UNSIGNED32 (WINAPI *ADSCONNECT_PTR)(
UNSIGNED8  *pucServerName,                                  ADSHANDLE
*phConnect );




[Non-text portions of this message have been removed]

Emmanuel Stapf

RE: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
> UNSIGNED32 AdsConnect (UNSIGNED8 *pucServerName, ADSHANDLE *phConnect);

It is actually quite simple. In an Eiffel class write the following:

        ads_connect (server_name, connect_handler: POINTER): NATURAL_32
                external
                        "C inline use %"ace.h%""
                alias
                        "return AdsConnect((UNSIGNED8 *) $server_name, (ADSHANDLE
*) $connect_handler);"
                end

Now, POINTER is not really Eiffel friendly so you need to abstract this a bit. For
server_name, if it is an ASCII string representation, then you could do the
following:


local
        c_str: C_STRING
        connect_handle: POINTER
do
        create c_str.make ("\\server\share")
        if ads_connect (c_str.item, $connect_handle) /= 0 then
                -- Handle error here
        else
                -- In theory you should have the connection handle in
`connect_handle'.
        end
end

Hope this helps,
Manu

------------------------------------------------------------------------  
Eiffel Software
805-685-1006
http://www.eiffel.com       
Customer support: http://support.eiffel.com       
User group: http://groups.eiffel.com/join       
------------------------------------------------------------------------  
luca.paganotti

Re: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
In reply to this post by dciphercomputing
--- In [hidden email], "dciphercomputing" <simonwhite@...> wrote:

>
> Hi
> I want to use the advantage client engine (ace) for the Advantage
> Database Server which is simply a Windows dll file (ace32.dll) in an
> Eiffel project.  I believe I have to create an Eiffel wrapper class with
> a method for every function available in the client engine.  However, I
> am not sure how this is done properly in Eiffel even after reading some
> of the documentation.  So I have included a sample function here in the
> hopes that someone might be able to show me the basic Eiffel class
> needed to wrap this function.  There is also an ace.h file which I
> assume will have to be referenced some how.
> Thanks,Simon
> Syntax
> UNSIGNED32 AdsConnect (UNSIGNED8 *pucServerName, ADSHANDLE *phConnect);
> Parameters
> pucServerName (I)Full file path of the data dictionary file, server
> name, or drive letter to which to connect. If the application uses a
> server name as the parameter, it must include the share name for
> Windows, path from the root for Linux, or volume name for Novell NetWare
> as well. For example, use "\\server\share", "\\server\path_from_root",
> or "\\server\volume". Linux users can also connect to the local machine
> using a direct path such as "/mydata". All Advantage clients and servers
> consider either slash type (forward or backslash) to be a path
> delimiter, this means you could also use a connection path with forward
> slashes, such as "//server/volume". Linux users should also reference
> the REPLACE_UNC_SERVER section in the ads.ini documentation.
> phConnect  (O)Return the connection handle if successful.
> The following items are taken from the ace.h  just in case they might be
> needed by anyone supplying an answer to this post.
> #ifndef ADSHANDLE_DEFINED   #define ADSHANDLE_DEFINED   #if defined( x64
> )      #if defined( ADS_LINUX )         // Long is 64 bits in GCC.
> typedef unsigned long  ADSHANDLE;      #else         typedef unsigned
> __int64  ADSHANDLE;      #endif   #else      typedef unsigned long
> ADSHANDLE;   #endif#endif
> UNSIGNED32 ENTRYPOINT AdsConnect( UNSIGNED8  *pucServerName,
> ADSHANDLE  *phConnect );typedef UNSIGNED32 (WINAPI *ADSCONNECT_PTR)(
> UNSIGNED8  *pucServerName,                                  ADSHANDLE
> *phConnect );
>
>
>
>
> [Non-text portions of this message have been removed]
>

Hi Simon,

I'm currently trying to write wrappers for libproj and me too finding trouble expecially with function pointers. Anyway just to take your first example, you should write something similar:

<c side>
--UNSIGNED32 AdsConnect (UNSIGNED8 *pucServerName, ADSHANDLE *phConnect);

<eiffel side>
...
feature

        ads_connect (server_name: POINTER; ads_handle: POINTER) : INTEGER
                        --
                external
                        "C inline use %"your_include_file_here%""
                alias
                        "[
                     <put your c calls here as you would have written them on the c side for example>
                        return AdsConnect($server_name, $ads_handle);
                        ]"
                end

this is an immediate way to get thing working,

more: inside your project's settings in EiffelStudio you have to define the location of the include files and the object files that the c compiler has to load to make the binding.

Anyway you should really read eiffel docs about C externals ;-) they are dense but with a bit of patience and attention you should work it out

In my case I defined the location of libproj header files and then point the object to the import library of libproj.

At this moment I'm able to use the main functions of the libproj API but function pointers seems to be a nightmare ...

If you work it out with them i would like to know how ;-)

There is also an Eiffel Wrapper Generator (EWG) that could help you, but unfortunately in my case I was not able even to compile it as compilation fails and I'm not able to understand why so I give up with it ... may be you're more lucky than me ...

Best regards

--------------------------------------------------------------
-- Dott. Ing. Luca Paganotti
-- Via dei Giardini 9
-- 21035 Cunardo (VA)
-- 393 1346898
--------------------------------------------------------------
-- sourceforge email:
-- [hidden email]
--------------------------------------------------------------
--



dciphercomputing

Re: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
In reply to this post by Emmanuel Stapf
Since I am use to using a Declare statement like the following example
DECLARE INTEGER ShellExecute IN shell32.dll ;
        INTEGER hndWin, ;
        STRING cAction, ;
        STRING cFileName, ;
        STRING cParams, ;
        STRING cDir, ;
        INTEGER nShowWin

cFileName = "c:\Program Files\Winzip\Winzip32.Exe"
cAction = "open"
ShellExecute(0,cAction,cFileName,"","",1)

I am trying to understand the Eiffel syntax and what it means so I have some more questions.

Why did you use the "C inline use %"ace.h%""h in the external as opposed to "C [dllwin32 %"ace32.dll%"]" ?  Where should the ace32.dll be located so that Eiffel can find it?

Secondly what is the definition of alias in the external so I understand how it is to be used.

Is this form also possible?

 if ads_connect ("\\server\share\", $connect_handle) /= 0 then

Thanks,
Simon



--- In [hidden email], "Emmanuel Stapf [ES]" <manus@...> wrote:

>
> > UNSIGNED32 AdsConnect (UNSIGNED8 *pucServerName, ADSHANDLE *phConnect);
>
> It is actually quite simple. In an Eiffel class write the following:
>
> ads_connect (server_name, connect_handler: POINTER): NATURAL_32
> external
> "C inline use %"ace.h%""
> alias
> "return AdsConnect((UNSIGNED8 *) $server_name, (ADSHANDLE
> *) $connect_handler);"
> end
>
> Now, POINTER is not really Eiffel friendly so you need to abstract this a bit. For
> server_name, if it is an ASCII string representation, then you could do the
> following:
>
>
> local
> c_str: C_STRING
> connect_handle: POINTER
> do
> create c_str.make ("\\server\share")
> if ads_connect (c_str.item, $connect_handle) /= 0 then
> -- Handle error here
> else
> -- In theory you should have the connection handle in
> `connect_handle'.
> end
> end
>
> Hope this helps,
> Manu
>


dciphercomputing

Re: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
In reply to this post by luca.paganotti
Hi

Thanks for the information.  I have been reading the C External documentation and slowly making progress.  It seems to me that it would be a very useful addition to EiffelStudio to have EWG has one of the available tools.  In another development environment I have used I could produce wrapper classes for COM objects which was very useful and saved a lot of work.  

Simon

--- In [hidden email], "luca.paganotti" <luca.paganotti@...> wrote:

>
> --- In [hidden email], "dciphercomputing" <simonwhite@> wrote:
> >
> > Hi
> > I want to use the advantage client engine (ace) for the Advantage
> > Database Server which is simply a Windows dll file (ace32.dll) in an
> > Eiffel project.  I believe I have to create an Eiffel wrapper class with
> > a method for every function available in the client engine.  However, I
> > am not sure how this is done properly in Eiffel even after reading some
> > of the documentation.  So I have included a sample function here in the
> > hopes that someone might be able to show me the basic Eiffel class
> > needed to wrap this function.  There is also an ace.h file which I
> > assume will have to be referenced some how.
> > Thanks,Simon
> > Syntax
> > UNSIGNED32 AdsConnect (UNSIGNED8 *pucServerName, ADSHANDLE *phConnect);
> > Parameters
> > pucServerName (I)Full file path of the data dictionary file, server
> > name, or drive letter to which to connect. If the application uses a
> > server name as the parameter, it must include the share name for
> > Windows, path from the root for Linux, or volume name for Novell NetWare
> > as well. For example, use "\\server\share", "\\server\path_from_root",
> > or "\\server\volume". Linux users can also connect to the local machine
> > using a direct path such as "/mydata". All Advantage clients and servers
> > consider either slash type (forward or backslash) to be a path
> > delimiter, this means you could also use a connection path with forward
> > slashes, such as "//server/volume". Linux users should also reference
> > the REPLACE_UNC_SERVER section in the ads.ini documentation.
> > phConnect  (O)Return the connection handle if successful.
> > The following items are taken from the ace.h  just in case they might be
> > needed by anyone supplying an answer to this post.
> > #ifndef ADSHANDLE_DEFINED   #define ADSHANDLE_DEFINED   #if defined( x64
> > )      #if defined( ADS_LINUX )         // Long is 64 bits in GCC.
> > typedef unsigned long  ADSHANDLE;      #else         typedef unsigned
> > __int64  ADSHANDLE;      #endif   #else      typedef unsigned long
> > ADSHANDLE;   #endif#endif
> > UNSIGNED32 ENTRYPOINT AdsConnect( UNSIGNED8  *pucServerName,
> > ADSHANDLE  *phConnect );typedef UNSIGNED32 (WINAPI *ADSCONNECT_PTR)(
> > UNSIGNED8  *pucServerName,                                  ADSHANDLE
> > *phConnect );
> >
> >
> >
> >
> > [Non-text portions of this message have been removed]
> >
>
> Hi Simon,
>
> I'm currently trying to write wrappers for libproj and me too finding trouble expecially with function pointers. Anyway just to take your first example, you should write something similar:
>
> <c side>
> --UNSIGNED32 AdsConnect (UNSIGNED8 *pucServerName, ADSHANDLE *phConnect);
>
> <eiffel side>
> ...
> feature
>
> ads_connect (server_name: POINTER; ads_handle: POINTER) : INTEGER
> --
> external
> "C inline use %"your_include_file_here%""
> alias
> "[
>     <put your c calls here as you would have written them on the c side for example>
>                         return AdsConnect($server_name, $ads_handle);
> ]"
> end
>
> this is an immediate way to get thing working,
>
> more: inside your project's settings in EiffelStudio you have to define the location of the include files and the object files that the c compiler has to load to make the binding.
>
> Anyway you should really read eiffel docs about C externals ;-) they are dense but with a bit of patience and attention you should work it out
>
> In my case I defined the location of libproj header files and then point the object to the import library of libproj.
>
> At this moment I'm able to use the main functions of the libproj API but function pointers seems to be a nightmare ...
>
> If you work it out with them i would like to know how ;-)
>
> There is also an Eiffel Wrapper Generator (EWG) that could help you, but unfortunately in my case I was not able even to compile it as compilation fails and I'm not able to understand why so I give up with it ... may be you're more lucky than me ...
>
> Best regards
>
> --------------------------------------------------------------
> -- Dott. Ing. Luca Paganotti
> -- Via dei Giardini 9
> -- 21035 Cunardo (VA)
> -- 393 1346898
> --------------------------------------------------------------
> -- sourceforge email:
> -- lucapaganotti@...
> --------------------------------------------------------------
> --
>


Emmanuel Stapf

RE: Re: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
> Thanks for the information.  I have been reading the C External
> documentation and slowly making progress.  It seems to me that it would
> be a very useful addition to EiffelStudio to have EWG has one of the

EWG-like tools are good to help you started when wrapping a large amount of
external code, but nothing replaces the human abstraction power. The WEL library
is a good example on how the Win32 API was abstracted whereas an automatic tool
would have been pretty limited.

> available tools.  In another development environment I have used I could
> produce wrapper classes for COM objects which was very useful and saved a
> lot of work.

We provide the EiffelCOM wizard exactly for that purpose. It reads a COM component
and generate automatically Eiffel wrappers to interact with it.

Regards,
Manu

------------------------------------------------------------------------  
Eiffel Software
805-685-1006
http://www.eiffel.com       
Customer support: http://support.eiffel.com       
User group: http://groups.eiffel.com/join       
------------------------------------------------------------------------  
Emmanuel Stapf

RE: Re: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
In reply to this post by dciphercomputing
> Since I am use to using a Declare statement like the following example
> DECLARE INTEGER ShellExecute IN shell32.dll ;
> INTEGER hndWin, ;
> STRING cAction, ;
> STRING cFileName, ;
> STRING cParams, ;
> STRING cDir, ;
> INTEGER nShowWin
>
> cFileName = "c:\Program Files\Winzip\Winzip32.Exe"
> cAction = "open"
> ShellExecute(0,cAction,cFileName,"","",1)

Microsoft knows exactly what they control and for STRING they do the marshalling
automatically. Eiffel is multiplatform and no automatic marshalling is done
between Eiffel types and external types.
 
> I am trying to understand the Eiffel syntax and what it means so I have
> some more questions.
>
> Why did you use the "C inline use %"ace.h%""h in the external as opposed
> to "C [dllwin32 %"ace32.dll%"]" ?  Where should the ace32.dll be located
> so that Eiffel can find it?

The dllwin32 is only required if you have need true dynamic loading (e.g. your exe
does not link against the .lib stub for the .dll). Otherwise using the plain C
inline is best.
 
> Secondly what is the definition of alias in the external so I understand
> how it is to be used.

The alias part needs to contain valid C code and you are free to put whatever you
want in it.
 
> Is this form also possible?
>
>  if ads_connect ("\\server\share\", $connect_handle) /= 0 then

Unfortunately not because of the required marshalling between the Eiffel string to
the C string, thus the usage of C_STRING in my previous post.

Regards,
Manu

------------------------------------------------------------------------  
Eiffel Software
805-685-1006
http://www.eiffel.com       
Customer support: http://support.eiffel.com       
User group: http://groups.eiffel.com/join       
------------------------------------------------------------------------  
dciphercomputing

Re: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
Thanks for the information.  I have got to get use to thinking about multi-platform and the issues of different internal formats. I forgot about the differences between Eiffel Strings and C strings etc.

Simon

--- In [hidden email], "Emmanuel Stapf [ES]" <manus@...> wrote:

>
> > Since I am use to using a Declare statement like the following example
> > DECLARE INTEGER ShellExecute IN shell32.dll ;
> > INTEGER hndWin, ;
> > STRING cAction, ;
> > STRING cFileName, ;
> > STRING cParams, ;
> > STRING cDir, ;
> > INTEGER nShowWin
> >
> > cFileName = "c:\Program Files\Winzip\Winzip32.Exe"
> > cAction = "open"
> > ShellExecute(0,cAction,cFileName,"","",1)
>
> Microsoft knows exactly what they control and for STRING they do the marshalling
> automatically. Eiffel is multiplatform and no automatic marshalling is done
> between Eiffel types and external types.
>  
> > I am trying to understand the Eiffel syntax and what it means so I have
> > some more questions.
> >
> > Why did you use the "C inline use %"ace.h%""h in the external as opposed
> > to "C [dllwin32 %"ace32.dll%"]" ?  Where should the ace32.dll be located
> > so that Eiffel can find it?
>
> The dllwin32 is only required if you have need true dynamic loading (e.g. your exe
> does not link against the .lib stub for the .dll). Otherwise using the plain C
> inline is best.
>  
> > Secondly what is the definition of alias in the external so I understand
> > how it is to be used.
>
> The alias part needs to contain valid C code and you are free to put whatever you
> want in it.
>  
> > Is this form also possible?
> >
> >  if ads_connect ("\\server\share\", $connect_handle) /= 0 then
>
> Unfortunately not because of the required marshalling between the Eiffel string to
> the C string, thus the usage of C_STRING in my previous post.
>
> Regards,
> Manu
>


dciphercomputing

Re: Newbie Question - How to wrap and external Windows dll in Eiffel?

Reply Threaded More More options
Print post
Permalink
In reply to this post by Emmanuel Stapf
Yes I can understand that but I am also thinking about the amount of time it will take to wrap the ace.h which is 4600 lines of code.  As a  person new to Eiffel this will take quite a while, however there are a lot of higher level things I need to work on so it seems EWG would be useful if it was technical possible to do.

Simon

--- In [hidden email], "Emmanuel Stapf [ES]" <manus@...> wrote:

>
> > Thanks for the information.  I have been reading the C External
> > documentation and slowly making progress.  It seems to me that it would
> > be a very useful addition to EiffelStudio to have EWG has one of the
>
> EWG-like tools are good to help you started when wrapping a large amount of
> external code, but nothing replaces the human abstraction power. The WEL library
> is a good example on how the Win32 API was abstracted whereas an automatic tool
> would have been pretty limited.
>
> > available tools.  In another development environment I have used I could
> > produce wrapper classes for COM objects which was very useful and saved a
> > lot of work.
>
> We provide the EiffelCOM wizard exactly for that purpose. It reads a COM component
> and generate automatically Eiffel wrappers to interact with it.
>
> Regards,
> Manu
>