Using DLLs with my Ruby app

Hi,

A new ruby user here. I want to try using ruby to use an API for
accessing and retrieving data from a server. After doing some research I
learned about ruby/dl and tried the following in irb:

ENV[‘PATH’] += “;C\projects\test\lib” # to include the dependecies of
the API
require ‘dl/import’

extend DL::Importable

dlload “myAPI.dll”

extern “void serverLogon(string, string, string, void, void)”

but I get an error stating that the symbol “serverLogon” can’t be found.
I’m pretty sure that I have the correct function name, but I downloaded
this DLL Export viewer to see the function names, and the application
lists the exported function as “_serverLogon@20”. I tried using
“_serverLogon@20” in extern but I got a “can’t parse the function
prototype” error.

I don’t really have much experience with using dlls and I feel like I’m
missing something here. Can anyone clarify why I’m unable to use the
functions in the dll provided and why it has such odd names?

Many thanks!

  • Grish

Have you tried without the @20 on the end?

On 14 Jul 2009, at 11:19, Gin Mendi wrote:

extend DL::Importable

dlload “myAPI.dll”

extern “void serverLogon(string, string, string, void, void)”

try:

extern “void _serverLogon(string, string, string, void, void)”

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason

On 14 Jul 2009, at 19:53, Gin Mendi wrote:

  • which results to a “can’t parse the function prototype” error.
    I’m not on a Windows box so I can’t easily test how dll function
    signatures work, however I suspect the problem is with extern not
    supporting the ‘@’ embedded in the function signature. As an
    alternative you can try the following:

require ‘dl’
dll = DL.dlopen(‘myAPI.dll’)
server_logon = dll[‘_serverLogon’, ‘0SSS00’]
server_logon.call …

where the 0s indicate a void pointer, and … is replaced with your
parameter list.

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason

Thanks for the replies!

Yes I tried out both:

  1. extern “void _serverLogon(string, string, string, void, void)”
  • which results to a “cannot find symbol” error.

and

  1. extern “void _serverLogon@20(string, string, string, void, void)”
  • which results to a “can’t parse the function prototype” error.

Thanks Ellie, I’m making a bit of progress here, this is what I did.

require ‘dl’
dll = DL.dlopen(“myAPI.dll”)
server_logon = dll["_serverLogon@20", “0SSS00”]
result = server_logon.call(“user”, “pass”, “address”, nil, nil)

now I get “DL::DLTypeError: unknown type ‘0’ of the return value.”

I really don’t have any experience with C or DLLs but I went through the
function specs and I tried using another logon function:

Handle serverLogonEx(LPCSTR username, LPCSTR password, LPCSTR
servername, EVENT_NOTIFY notify, LPVOID userdata)

Handle is a type definition of LPVOID, while EVENT_NOTIFY is a function
callback. These are all a little new to me since I have no experience
with C but just reading online and putting things together. This is now
what I tried:

require ‘dl’
dll = DL.dlopen(“myAPI.dll”)
server_logon = dll["_serverLogonEx@20", “PcccPP”] # still putting @20
result = server_logon.call(“user”, “pass”, “some_address”, nil, nil)

and I get the following results:
OpenPipe error 1113 - \unknown type ‘0’ of the
return value.\pipe\dbserver

but I get a return from irb:
[nil, [117, 112, 49, nil, nil]]

I’m guessing the first element in that array is the returned value and
the 2nd element which is an array was my original paramters passed?
Perhaps I’m defining my function incorrectly?

Eleanor McHugh wrote in post #834844:

On 14 Jul 2009, at 11:19, Gin Mendi wrote:

extend DL::Importable

dlload “myAPI.dll”

extern “void serverLogon(string, string, string, void, void)”

try:

extern “void _serverLogon(string, string, string, void, void)”

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason

Hi, I am a newbiew to this to but I think I am way behind you in my
understanding. Can someone explain why the ‘extern’ is used here? Is it
mandatory to use this if you want to call a method from a dll?