DL usage / DL documentation

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 wrote:

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

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

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

PGP.sig (186 Bytes)

···

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?

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

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

Eric Hodel 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

···

On 28 Mar 2005, at 09:59, Stephan Kämper wrote:

Eric Hodel 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

···

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

On 28 Mar 2005, at 09:59, Stephan Kämper wrote:

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

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

Eric Hodel 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.

···

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

On 28 Mar 2005, at 09:59, Stephan Kämper wrote:

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