Loading ...
Sorry, an error occurred while loading the content.

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

Expand Messages
  • dciphercomputing
    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
    Message 1 of 9 , Oct 1, 2009
    • 0 Attachment
      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 [ES]
      ... 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
      Message 2 of 9 , Oct 1, 2009
      • 0 Attachment
        > 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
      • luca.paganotti
        ... 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
        Message 3 of 9 , Oct 1, 2009
        • 0 Attachment
          --- In eiffel_software@yahoogroups.com, "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@...
          --------------------------------------------------------------
          --
        • 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
          Message 4 of 9 , Oct 1, 2009
          • 0 Attachment
            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 eiffel_software@yahoogroups.com, "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
            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
            Message 5 of 9 , Oct 1, 2009
            • 0 Attachment
              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 eiffel_software@yahoogroups.com, "luca.paganotti" <luca.paganotti@...> wrote:
              >
              > --- In eiffel_software@yahoogroups.com, "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 [ES]
              ... 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
              Message 6 of 9 , Oct 1, 2009
              • 0 Attachment
                > 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
              • Emmanuel Stapf [ES]
                ... Microsoft knows exactly what they control and for STRING they do the marshalling automatically. Eiffel is multiplatform and no automatic marshalling is
                Message 7 of 9 , Oct 1, 2009
                • 0 Attachment
                  > 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
                  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
                  Message 8 of 9 , Oct 2, 2009
                  • 0 Attachment
                    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 eiffel_software@yahoogroups.com, "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
                    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
                    Message 9 of 9 , Oct 2, 2009
                    • 0 Attachment
                      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 eiffel_software@yahoogroups.com, "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
                      >
                    Your message has been successfully submitted and would be delivered to recipients shortly.