[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

DL usage / DL documentation

Stephan Kämper

3/28/2005 5:59:00 PM

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/r... )

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
6 Answers

Florian Gross

3/28/2005 6:29:00 PM

0

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

Stephan Kämper

3/28/2005 8:09:00 PM

0

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

Thanks for the link!
However, these examples seem to refer to ruby-dl2
http://rubyforge.org/projects... (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

3/28/2005 9:44:00 PM

0

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:

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

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

Stephan Kämper

3/29/2005 1:45:00 PM

0

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

3/29/2005 7:04:00 PM

0


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 - drbrain@segment7.net - http://se...
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04




Eric Hodel

3/29/2005 7:15:00 PM

0

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 - drbrain@segment7.net - http://se...
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04