DL usage / DL documentation

Discussion in 'Ruby' started by Stephan Kämper, Mar 28, 2005.

  1. Hi all,

    I currently try to call a function in a DLL, which has a prototype like
    this:

    int test(int an_int, long * a_ptr_to_long, char * a_string);

    How do I get a 'long *' into the method from Ruby using DL?

    In C++ I'd just define a corresponding variable and pass its address:

    long a_long;
    int res = int test( 42, &a_long, "help me please" );


    (Gee, I haven't programmed C++ a long time...)

    But how do I do that from Ruby? (It seems I just don't understand this
    document: http://www.jbrowse.com/text/rdl_en.html )

    Is there some more comprehensive documentation about DL out there?
    Should I switch to the recently announced DL2 version 0.4?

    Any help is really appreciated.

    Stephan
     
    Stephan Kämper, Mar 28, 2005
    #1
    1. Advertising

  2. Stephan Kämper wrote:

    > How do I get a 'long *' into the method from Ruby using DL?


    Have a look at GetDiskFreeSpace in http://rubyurl.com/k7A8T
     
    Florian Gross, Mar 28, 2005
    #2
    1. Advertising

  3. Florian Gross wrote:
    > Stephan Kämper wrote:
    >
    >> How do I get a 'long *' into the method from Ruby using DL?

    >
    > Have a look at GetDiskFreeSpace in http://rubyurl.com/k7A8T


    Thanks for the link!
    However, these examples seem to refer to ruby-dl2
    http://rubyforge.org/projects/ruby-dl2/ (unless I'm completely mistaken,
    which might well be the case..).

    Currently I'm running the One-Click-Installer (1.8.2-14 Final), which
    apparently provides an earlier version of DL - which brings me back to
    one of my other questions: Should I switch to the recently announced DL2
    version 0.4? What are the pros & cons of switching.
    How stable may I expect 0.4 to be?

    Happy rubying

    Stephan
     
    Stephan Kämper, Mar 28, 2005
    #3
  4. Stephan Kämper

    Eric Hodel Guest

    --Apple-Mail-5-595035190
    Content-Transfer-Encoding: quoted-printable
    Content-Type: text/plain; charset=ISO-8859-1; format=flowed

    On 28 Mar 2005, at 09:59, Stephan K=E4mper wrote:

    > Hi all,
    >
    > I currently try to call a function in a DLL, which has a prototype=20
    > like this:
    >
    > int test(int an_int, long * a_ptr_to_long, char * a_string);
    >
    > How do I get a 'long *' into the method from Ruby using DL?


    DL just does it:

    require "dl"
    require "dl/import"
    require "dl/struct"

    module LIBC

    extend DL::Importable

    dlload "libc.dylib"

    typealias "const time_t *clock", "long ref"

    StructTm =3D struct [
    "int tm_sec", # seconds (0 - 60)
    "int tm_min", # minutes (0 - 59)
    "int tm_hour", # hours (0 - 23)
    "int tm_mday", # day of month (1 - 31)
    "int tm_mon", # month of year (0 - 11)
    "int tm_year", # year - 1900
    "int tm_wday", # day of week (Sunday =3D 0)
    "int tm_yday", # day of year (0 - 365)
    "int tm_isdst", # is summer time in effect?
    "long tm_gmtoff", # offset from UTC in seconds
    "char *tm_zone", # abbreviation of timezone name
    ]

    extern "struct tm * localtime(const time_t *clock)"

    def self.c_localtime(clock)
    tm =3D LIBC.localtime(clock)
    return LIBC::StructTm.new(tm)
    end

    end

    p LIBC.c_localtime(Time.now.to_i).tm_min

    --=20
    Eric Hodel - - http://segment7.net
    FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

    --Apple-Mail-5-595035190
    content-type: application/pgp-signature; x-mac-type=70674453;
    name=PGP.sig
    content-description: This is a digitally signed message part
    content-disposition: inline; filename=PGP.sig
    content-transfer-encoding: 7bit

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (Darwin)

    iD8DBQFCSHqRMypVHHlsnwQRAm6dAJ94rXa1yuE/F4C6XXhR2tzjFp8angCeK3yP
    hHiODN1D0bAY3oBoTBroyCM=
    =yUa6
    -----END PGP SIGNATURE-----

    --Apple-Mail-5-595035190--
     
    Eric Hodel, Mar 28, 2005
    #4
  5. Eric Hodel wrote:
    > On 28 Mar 2005, at 09:59, Stephan Kämper wrote:
    >
    >> Hi all,
    >>
    >> I currently try to call a function in a DLL, which has a prototype
    >> like this:
    >>
    >> int test(int an_int, long * a_ptr_to_long, char * a_string);
    >>
    >> How do I get a 'long *' into the method from Ruby using DL?

    >
    > DL just does it:


    Thanks for answering. I'm sure it does. But apparently I'm a bit stupid
    these days - I still don't get it. <blush/>

    > require "dl"
    > require "dl/import"
    > require "dl/struct"
    >
    > module LIBC
    >
    > extend DL::Importable
    >
    > dlload "libc.dylib"
    >
    > typealias "const time_t *clock", "long ref"


    What does the 'clock' and 'ref' part mean it this typealias?
    Does that mean a "const time_t *" is just another (type) name for "long"?

    > StructTm = struct [
    > "int tm_sec", # seconds (0 - 60)
    > "int tm_min", # minutes (0 - 59)
    > "int tm_hour", # hours (0 - 23)
    > "int tm_mday", # day of month (1 - 31)
    > "int tm_mon", # month of year (0 - 11)
    > "int tm_year", # year - 1900
    > "int tm_wday", # day of week (Sunday = 0)
    > "int tm_yday", # day of year (0 - 365)
    > "int tm_isdst", # is summer time in effect?
    > "long tm_gmtoff", # offset from UTC in seconds
    > "char *tm_zone", # abbreviation of timezone name
    > ]
    >
    > extern "struct tm * localtime(const time_t *clock)"
    >
    > def self.c_localtime(clock)
    > tm = LIBC.localtime(clock)
    > return LIBC::StructTm.new(tm)
    > end
    >
    > end
    >
    > p LIBC.c_localtime(Time.now.to_i).tm_min


    What would I have to do if the called DLL function changes the thing
    pointed to?

    I'll just return to 'my' function mentioned above:
    > int test(int an_int, long * a_ptr_to_long, char * a_string);


    As far as I understood, something like this might be a start:

    require "dl"
    require "dl/import"
    require "dl/struct"

    module Foo
    extend DL::Importable
    dlload "mylinb.dll"
    extern "int test(int, long *, char)"
    end

    # Now create some variables, to pass into 'Foo.test'

    index = 42
    name = "F. Prefect"

    # ... missing code here to create ptr_to_long

    ret = Foo.test( index, ptr_to_long, name )

    How (I think) that's my question: How can I creatthat ptr_to_long thing
    - and how would I get back the value (to which it points after the
    function call)?

    Still confused (I should incorporate some C/C++ in one of my next
    projects to used to pointers and pointees again...)

    Happy rubying

    Stephan
     
    Stephan Kämper, Mar 29, 2005
    #5
  6. Stephan Kämper

    Eric Hodel Guest

    On 29 Mar 2005, at 05:49, Stephan Kämper wrote:

    > Eric Hodel wrote:
    >> On 28 Mar 2005, at 09:59, Stephan Kämper wrote:
    >>> Hi all,
    >>>
    >>> I currently try to call a function in a DLL, which has a prototype
    >>> like this:
    >>>
    >>> int test(int an_int, long * a_ptr_to_long, char * a_string);
    >>>
    >>> How do I get a 'long *' into the method from Ruby using DL?

    >> DL just does it:

    >
    > Thanks for answering. I'm sure it does. But apparently I'm a bit
    > stupid these days - I still don't get it. <blush/>
    >
    >> require "dl"
    >> require "dl/import"
    >> require "dl/struct"
    >> module LIBC
    >> extend DL::Importable
    >> dlload "libc.dylib"
    >> typealias "const time_t *clock", "long ref"

    >
    > What does the 'clock' and 'ref' part mean it this typealias?
    > Does that mean a "const time_t *" is just another (type) name for
    > "long"?
    >
    >> StructTm = struct [
    >> "int tm_sec", # seconds (0 - 60)
    >> "int tm_min", # minutes (0 - 59)
    >> "int tm_hour", # hours (0 - 23)
    >> "int tm_mday", # day of month (1 - 31)
    >> "int tm_mon", # month of year (0 - 11)
    >> "int tm_year", # year - 1900
    >> "int tm_wday", # day of week (Sunday = 0)
    >> "int tm_yday", # day of year (0 - 365)
    >> "int tm_isdst", # is summer time in effect?
    >> "long tm_gmtoff", # offset from UTC in seconds
    >> "char *tm_zone", # abbreviation of timezone name
    >> ]
    >> extern "struct tm * localtime(const time_t *clock)"
    >> def self.c_localtime(clock)
    >> tm = LIBC.localtime(clock)
    >> return LIBC::StructTm.new(tm)
    >> end
    >> end
    >> p LIBC.c_localtime(Time.now.to_i).tm_min

    >
    > What would I have to do if the called DLL function changes the thing
    > pointed to?
    >
    > I'll just return to 'my' function mentioned above:
    > > int test(int an_int, long * a_ptr_to_long, char * a_string);

    >
    > As far as I understood, something like this might be a start:
    >
    > require "dl"
    > require "dl/import"
    > require "dl/struct"
    >
    > module Foo
    > extend DL::Importable
    > dlload "mylinb.dll"
    > extern "int test(int, long *, char)"
    > end
    >
    > # Now create some variables, to pass into 'Foo.test'
    >
    > index = 42
    > name = "F. Prefect"
    >
    > # ... missing code here to create ptr_to_long
    >
    > ret = Foo.test( index, ptr_to_long, name )
    >
    > How (I think) that's my question: How can I creatthat ptr_to_long
    > thing - and how would I get back the value (to which it points after
    > the function call)?
    >
    > Still confused (I should incorporate some C/C++ in one of my next
    > projects to used to pointers and pointees again...)
    >
    > Happy rubying
    >
    > Stephan
    >


    --
    Eric Hodel - - http://segment7.net
    FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
     
    Eric Hodel, Mar 29, 2005
    #6
  7. Stephan Kämper

    Eric Hodel Guest

    Whoops, that last one made it out the door due to an accidental mouse
    click.

    On 29 Mar 2005, at 05:49, Stephan Kämper wrote:

    > Eric Hodel wrote:
    >> On 28 Mar 2005, at 09:59, Stephan Kämper wrote:
    >>> Hi all,
    >>>
    >>> I currently try to call a function in a DLL, which has a prototype
    >>> like this:
    >>>
    >>> int test(int an_int, long * a_ptr_to_long, char * a_string);
    >>>
    >>> How do I get a 'long *' into the method from Ruby using DL?

    >> DL just does it:

    >
    > Thanks for answering. I'm sure it does. But apparently I'm a bit
    > stupid these days - I still don't get it. <blush/>
    >
    >> require "dl"
    >> require "dl/import"
    >> require "dl/struct"
    >> module LIBC
    >> extend DL::Importable
    >> dlload "libc.dylib"
    >> typealias "const time_t *clock", "long ref"

    >
    > What does the 'clock' and 'ref' part mean it this typealias?
    > Does that mean a "const time_t *" is just another (type) name for
    > "long"?


    The header for localtime is "struct tm *localtime(const time_t *);"

    I shouldn't need the clock in there, but even still DL doesn't know
    what a time_t is (it's a long on most 32 bit platforms), so typealias
    teaches DL what a time_t * really is (the same as "long *", which is a
    "long ref", see dl/types.rb).

    >> extern "struct tm * localtime(const time_t *clock)"
    >> def self.c_localtime(clock)
    >> tm = LIBC.localtime(clock)
    >> return LIBC::StructTm.new(tm)
    >> end
    >> end
    >> p LIBC.c_localtime(Time.now.to_i).tm_min

    >
    > What would I have to do if the called DLL function changes the thing
    > pointed to?
    >
    > I'll just return to 'my' function mentioned above:
    > > int test(int an_int, long * a_ptr_to_long, char * a_string);

    >
    > As far as I understood, something like this might be a start:
    >
    > require "dl"
    > require "dl/import"
    > require "dl/struct"
    >
    > module Foo
    > extend DL::Importable
    > dlload "mylinb.dll"
    > extern "int test(int, long *, char)"

    extern "int test(int, long *, char *)"
    > end
    >
    > # Now create some variables, to pass into 'Foo.test'
    >
    > index = 42
    > name = "F. Prefect"
    >
    > # ... missing code here to create ptr_to_long
    >
    > ret = Foo.test( index, ptr_to_long, name )
    >
    > How (I think) that's my question: How can I creatthat ptr_to_long
    > thing - and how would I get back the value (to which it points after
    > the function call)?


    If you don't need the value back:

    ret = Foo.test(42, 3, "F. Prefect")

    DL automatically turns the number you pass in into a pointer for you.

    I'm not sure how you'd be able to get at the value if the function
    changes the value of the pointer, though. That section seems to be
    missing from all the documentation I've looked at.

    --
    Eric Hodel - - http://segment7.net
    FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
     
    Eric Hodel, Mar 29, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. metfan
    Replies:
    2
    Views:
    4,885
    Robert Olofsson
    Oct 21, 2003
  2. Colin J. Williams

    Webchecker Usage - a problem with local usage

    Colin J. Williams, Feb 25, 2004, in forum: Python
    Replies:
    1
    Views:
    574
    Colin J. Williams
    Feb 26, 2004
  3. Cameron Laird
    Replies:
    1
    Views:
    691
    Josiah Carlson
    Apr 3, 2004
  4. Kenneth McDonald
    Replies:
    2
    Views:
    790
  5. Replies:
    1
    Views:
    1,263
    Andy Dingley
    Sep 16, 2006
Loading...

Share This Page