Using a DLL that wants a function pointer

D

daniel åkerud

[Note: parts of this message were removed to make it a legal post.]

I want to use a DLL with Ruby (Win32). This DLL has X number of functions,
and one of these takes a function pointer. The DLL will call this
callback-function when some data arrives. I cannot figure out how to do this
in Ruby. Is it possible? If not, any tips on how to circumvent this
restriction? _Any_ hints appreciated.

/D
 
L

Lloyd Linklater

daniel said:
I want to use a DLL with Ruby (Win32). This DLL has X number of
functions,
and one of these takes a function pointer. The DLL will call this
callback-function when some data arrives. I cannot figure out how to do
this
in Ruby. Is it possible? If not, any tips on how to circumvent this
restriction? _Any_ hints appreciated.

It is with fear and trembling that I post here, but I did not want
nothing to be said, so take this with the proverbial salt lick until
someone that knows can answer.

Using pointers from an interpreted language is not something that should
work and, if it does, I expect that it will be ugly.

Here is what I would do if I had no other way to do, and, at the moment,
I don't. I would make an intermediary program that handles the
pointers and talks to both your ruby app and the DLL in question using
something simple. You did not say which language the DLL was written
in, so I will assume that it is C/C++. Personally, I work with Delphi
and a pascal DLL is compiled a bit differently. Also, if it is compiled
for windows, they use the FAR PASCAL call to make it run faster, though
Mr. Bill changed the name because he hates pascal.

You can experiment to find how it all works together but it is at least
something. I admit that it is ugly in the extreme, but it is a place to
start if nothing more elegant gets offered.

GL!
 
Y

yermej

[Note: parts of this message were removed to make it a legal post.]

I want to use a DLL with Ruby (Win32). This DLL has X number of functions,
and one of these takes a function pointer. The DLL will call this
callback-function when some data arrives. I cannot figure out how to do this
in Ruby. Is it possible? If not, any tips on how to circumvent this
restriction? _Any_ hints appreciated.

/D

I haven't tried it before, but look into Win32::API::Callback. Most of
my googling returned threads where people were having problems with
it, but that might give you examples to get started with. Here's one
of them:
http://rubyforge.org/pipermail/win32utils-devel/2008-January/000985.html

Look for where SNMPAPI_CALLBACK is defined. It appears that Callback
takes two arguments - the first is the parameter signature notated the
same as when you use an API method. The second would be the return
signature. Following that is the body of the callback as a block.
 
D

daniel åkerud

[Note: parts of this message were removed to make it a legal post.]

I want to use a DLL with Ruby (Win32). This DLL has X number of functions,
and one of these takes a function pointer. The DLL will call this
callback-function when some data arrives. I cannot figure out how to do this
in Ruby. Is it possible? If not, any tips on how to circumvent this
restriction? _Any_ hints appreciated.

/D

I haven't tried it before, but look into Win32::API::Callback. Most of
my googling returned threads where people were having problems with
it, but that might give you examples to get started with. Here's one
of them:
http://rubyforge.org/pipermail/win32utils-devel/2008-January/000985.html

Look for where SNMPAPI_CALLBACK is defined. It appears that Callback
takes two arguments - the first is the parameter signature notated the
same as when you use an API method. The second would be the return
signature. Following that is the body of the callback as a block.
Thanks for the answers,

Today I have been working with creating Ruby extensions, and I got this
idea: What about I pass a Proc.new object to a method in the extension, and
when the extension gets a callback from the DLL, it calls the Proc object.
This would work right? I havn't seen an example of an extension that manage=
s
a Proc object though and calls it, but if someone says this sounds
reasonable i'll do this.

/D
 
D

daniel åkerud

[Note: parts of this message were removed to make it a legal post.]

I want to use a DLL with Ruby (Win32). This DLL has X number of functions,
and one of these takes a function pointer. The DLL will call this
callback-function when some data arrives. I cannot figure out how to do this
in Ruby. Is it possible? If not, any tips on how to circumvent this
restriction? _Any_ hints appreciated.

/D

I haven't tried it before, but look into Win32::API::Callback. Most of
my googling returned threads where people were having problems with
it, but that might give you examples to get started with. Here's one
of them:
http://rubyforge.org/pipermail/win32utils-devel/2008-January/000985.htm= l

Look for where SNMPAPI_CALLBACK is defined. It appears that Callback
takes two arguments - the first is the parameter signature notated the
same as when you use an API method. The second would be the return
signature. Following that is the body of the callback as a block.
Thanks for the answers,

Today I have been working with creating Ruby extensions, and I got this
idea: What about I pass a Proc.new object to a method in the extension,
and when the extension gets a callback from the DLL, it calls the Proc
object. This would work right? I havn't seen an example of an extension t= hat
manages a Proc object though and calls it, but if someone says this sound= s
reasonable i'll do this.

/D
I think this is important in this context: The callback is called from
another thread, i.e. the DLL creates a thread that reads data in the
background, and when data arrives it calls the callback. Would this be a
problem if the Ruby extension calls the Proc object from another thread, an=
d
if so, how to solve it...

/D
 
D

Daniel Berger

I think this is important in this context: The callback is called from
another thread, i.e. the DLL creates a thread that reads data in the
background, and when data arrives it calls the callback. Would this be a
problem if the Ruby extension calls the Proc object from another thread, a= nd
if so, how to solve it...

At the moment, you don't. Windows callbacks occur in their own native
thread. The Ruby interpreter isn't thread safe. You'll get one
callback call to work, but after that it will probably segfault.

Heesob is working on this for the C side of the house to see if he can
come up with a way to make it work. In the meantime, I'm going to see
if I can get win32-api ported to JRuby using JNA this weekend. That
*should* work, though it means you'll have to use JRuby to use it,
which may not be such a bad thing. :)

Regards,

Dan
 
D

daniel åkerud

,

At the moment, you don't. Windows callbacks occur in their own native
thread. The Ruby interpreter isn't thread safe. You'll get one
callback call to work, but after that it will probably segfault.

Heesob is working on this for the C side of the house to see if he can
come up with a way to make it work. In the meantime, I'm going to see
if I can get win32-api ported to JRuby using JNA this weekend. That
*should* work, though it means you'll have to use JRuby to use it,
which may not be such a bad thing. :)

Regards,

Dan
What if I provide a polling-mechanism, i.e. the Ruby-extension puts all dat=
a
from the callback in a queue, and the Ruby-script poll()s periodically to
see if there is any data. In this case, to Ruby, everything will happen in
the same thread. Indeed this removes the callback interface Ruby-Script ->
Ruby-Extension (which indeed is the subject...), but it circumvents the
threading-problem. Would it work?

/D
 
J

Jari Williamsson

daniel said:
What if I provide a polling-mechanism, i.e. the Ruby-extension puts all data
from the callback in a queue, and the Ruby-script poll()s periodically to
see if there is any data. In this case, to Ruby, everything will happen in
the same thread. Indeed this removes the callback interface Ruby-Script ->
Ruby-Extension (which indeed is the subject...), but it circumvents the
threading-problem. Would it work?

Yes, that would work if you make the data queue thread safe, probably
using a Windows mutex (and wait with no timeout duration in the Ruby
thread).


Best regards,

Jari Williamsson
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,526
Members
44,997
Latest member
mileyka

Latest Threads

Top