help using windows dlls and pointers

D

dafritz

Ive been writing a program that uses a windows dll to write spss files.
This is my first experience using dlls in ruby and am fairly
inexperienced with the ruby language as well. The problem I am having
is recieving pointer values that should be returned through a
referenced object.

For example...


create_file = Win32API.new("spssio32.dll", "spssOpenWrite", ['P', 'P'],
'I')

takes a file name and a pointer which acts as the file handle. once the
file is created the handle is stored in the file handle and returned by
reference. My call to the function looks like this:

@file_handle=""
puts create_file.Call("testFile.sav", @file_handle)

The return value of the function is simply 0 for success or one of
several other various return error codes. I am recieving a return value
of 0 and the file is being created which is good, however, when i use
@file_handle for future calls to other functions to actually write to
the file, i get a return value of "Invalid File Handle." when i display
@file_handle i get 'nil'.

I was hoping someone here could help explain why the file pointer is
not being stored in @file_handle. Do i need to use pack and unpack to
extract this data? for reference here is a quick description of the
spssOpenWrite and a small c++ example.

___________________________________________________________-
int spssOpenWrite (const char *filename, int *handle)

Description
This function opens a file in preparation for creating a new SPSS data
file and returns
a handle that should be used for subsequent operations on the file.

Parameter Description
filename Name of the data file
handle Pointer to handle to be returned


Returns
One of the following codes. Success is indicated by zero (SPSS_OK),
errors by positive
values, and warnings, if any, by negative values.
Error Code Description
SPSS_OK No error
SPSS_FITAB_FULL File table full (too many open SPSS data
files)
SPSS_FILE_OERROR Error opening file
SPSS_NO_MEMORY Insufficient memory

Example

#include "spssdio.h"
void func()
{
int fH; /* file handle */
int error; /* error code */
...
error = spssOpenWrite("dat.sav", &fH);
if (error == 0)
{
/* fH is a valid handle; process and */
...
/* close file */
error = spssCloseWrite(fH);
...
}
else
{
/* Handle error*/
...
}
}
 
C

ChrisH

Is the filehandle reurned the same as a 'file descritpor'?

If so could try IO.new( filehandle , 'r') to produce a Ruby File
object...
 
D

dafritz

Doesnt appear to be as the following function calls (ex:
spss_set_var(file handle, variable name, variable type)) needs to take
a pointer(or string in ruby) the documentation for this Win32API and
pointers states the following:

The Win32API module allows access to any arbitrary Windows 32 function.
Many of these functions take or return a Pointer datatype---a region
of memory corresponding to a C string or structure type.

In Ruby, these pointers are represented using class String, which
contains a sequence of 8-bit bytes. It is up to you to pack and unpack
the bits in the String.
 
D

dafritz

Im sure there would be a round about way of using that, but im looking
for a more eligant solution that only uses the functionality of the
spss dll file. Im sure this function passes the handle back into
@file_handle because i wrote a working implementation in c++, however
im just looking for my error in coding it in ruby. I cant understand
why @file_handle never changes when the function is called (it stays
nil). This is more a problem of my knowledge of how ruby operates
rather than looking for a solution in other libraries. From reading
other posts of using Win32API it appears that pointers can be passed
back from the dll call by reference.
 
D

dafritz

Here is the full code in ruby of what im trying to get working

require 'Win32API'

@file_handle= " "* 4
@var_handle=" "

create_file = Win32API.new("spssio32.dll", "spssOpenWrite", ['P','P'],
'I')
spss_set_var=Win32API.new("spssio32.dll", "spssSetVarName", ['P', 'P',
'I'], 'I')
commit_header=Win32API.new("spssio32.dll", "spssCommitHeader", ['P'],
'V')
close_file =Win32API.new("spssio32.dll", "spssCloseWrite", ['P'], 'V')

puts create_file.Call("testFile.sav", @file_handle) #puts 0 for
succesfully creating the file
puts spss_set_var.Call(@file_handle, "ruby_spss_test", 0) # puts 5 for
invalid file handle

# dont care about these until i get the previous line to output 0 for
success
commit_header.Call(@file_handle)
close_file.Call(@file_handle)
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top