Ruby/DL Question

G

gregarican

I am trying to call a method included in a Windows DLL file. Judging by
the C header file that this DLL is created from and judging from the
API documentation I think I have the various parameters needed. But the
return code seems to be different. I have commented my code to include
the C header details as well as a sample C program that accesses this
method. Anyone know what I am missing? I guess I'm confused because the
method is supposed to return an integer result code, but also returns a
pointer called acsHandle. I thought only one thing could be returned
and that's why my Ruby code is just returning the acsHandle pointer...

=begin
acsOpenStream method based on

TSAPI
acsOpenStream ( acsHandle /* RETURN */
invokeIDType, /* INPUT */
invokeID, /* INPUT */
streamType, /* INPUT */
serverID, /* INPUT */
loginID, /* INPUT */
passwd, /* INPUT */
applicationName,/* INPUT */
acsLevelReq, /* INPUT */
apiVer, /* INPUT */
sendQSize, /* INPUT */
sendExtraBufs, /* INPUT */
recvQSize, /* INPUT */
recvExtraBufs, /* INPUT */
privateData /* INPUT */);

here's an example of this in C

rCode=acsOpenStream(acsHandle,invokeIDType,invokeID,streamType,

serverID,loginID,passwd,applicationName,acsLevelReq,

apiVer,sendQSize,sendExtraBufs,recvQSize,recvExtraBufs,

privateData);

if (rCode < 0)<
{

printf("acsOpenStream failure...");

return;

}

else

{

printf("acsOpenStream success\n");

invokeID=rCode;

}

=end

# here's my Ruby code

require 'dl'
csta=DL.dlopen('csta32.dll')
openStream=csta['acsOpenStream', 'PSISSSSSISIIIIS']
results=openStream.call("LIB_GEN_ID",0,"ST_CSTA","AVAYA#MERLIN#CSTA#MERLIN-CTI\000","username\000","password\000","CTI
Test\000",2,"TS2",0,0,0,0,nil)
p results

# my results show as
# [#<DL::ptrData:0x02ABD620 ptr=0xFFFFFFFE size=0 free=0x00000000>,
["LIB_GEN_ID",0,"ST_CSTA","AVAYA#MERLIN#CSTA#MERLIN-CTI\000","username\000","password\000","CTI
Test\000",2,"TS2",0,0,0,0,nil]]
 
T

Takaaki Tateishi

gregarican said:
I am trying to call a method included in a Windows DLL file. Judging by
the C header file that this DLL is created from and judging from the
API documentation I think I have the various parameters needed. But the
return code seems to be different. I have commented my code to include
the C header details as well as a sample C program that accesses this
method. Anyone know what I am missing? I guess I'm confused because the
method is supposed to return an integer result code, but also returns a
pointer called acsHandle. I thought only one thing could be returned
and that's why my Ruby code is just returning the acsHandle pointer...

=begin
acsOpenStream method based on

TSAPI
acsOpenStream ( acsHandle /* RETURN */
invokeIDType, /* INPUT */
invokeID, /* INPUT */
streamType, /* INPUT */
serverID, /* INPUT */
loginID, /* INPUT */
passwd, /* INPUT */
applicationName,/* INPUT */
acsLevelReq, /* INPUT */
apiVer, /* INPUT */
sendQSize, /* INPUT */
sendExtraBufs, /* INPUT */
recvQSize, /* INPUT */
recvExtraBufs, /* INPUT */
privateData /* INPUT */);

here's an example of this in C

rCode=acsOpenStream(acsHandle,invokeIDType,invokeID,streamType,

serverID,loginID,passwd,applicationName,acsLevelReq,

apiVer,sendQSize,sendExtraBufs,recvQSize,recvExtraBufs,

privateData);

if (rCode < 0)<
{

printf("acsOpenStream failure...");

return;

}

else

{

printf("acsOpenStream success\n");

invokeID=rCode;

}

=end

# here's my Ruby code

require 'dl'
csta=DL.dlopen('csta32.dll')
openStream=csta['acsOpenStream', 'PSISSSSSISIIIIS']
results=openStream.call("LIB_GEN_ID",0,"ST_CSTA","AVAYA#MERLIN#CSTA#MERLIN-CTI\000","username\000","password\000","CTI
Test\000",2,"TS2",0,0,0,0,nil)
p results

# my results show as
# [#<DL::ptrData:0x02ABD620 ptr=0xFFFFFFFE size=0 free=0x00000000>,
["LIB_GEN_ID",0,"ST_CSTA","AVAYA#MERLIN#CSTA#MERLIN-CTI\000","username\000","password\000","CTI
Test\000",2,"TS2",0,0,0,0,nil]]
 
T

Takaaki Tateishi

gregarican said:
method. Anyone know what I am missing? I guess I'm confused because the
method is supposed to return an integer result code, but also returns a
pointer called acsHandle. ....
openStream=csta['acsOpenStream', 'PSISSSSSISIIIIS']

I think the above line should be csta['acsOpenStream', 'IPSISSSSSISIIIIS'].
As you can see, I put 'I' before the 'PSISS....' since the method is supposed to
return an integer value.

Regards,
 
G

gregarican

Takaaki said:
I think the above line should be csta['acsOpenStream', 'IPSISSSSSISIIIIS'].
As you can see, I put 'I' before the 'PSISS....' since the method is supposed to
return an integer value.


I made the change to include the integer return value, and removed the
P entry since the pointer was no longer in the picture. In addition I
checked the parameter data types to ensure that they matched. There
were a couple of entries that I originally had as strings which were
actually enum types in the C header file. So I went in and found the
corresponding integer values they represent. Now my code looks like:
----------------------------------------
=begin
TSAPI
acsOpenStream (acsHandle /* RETURN an integer value? */
invokeIDType, /* INPUT an integer ENUM value?*/
invokeID, /* INPUT an integer value? */
streamType, /* INPUT an integer ENUM value? */
serverID, /* INPUT a null terminated string value? */
loginID, /* INPUT a null terminated string value? */
passwd, /* INPUT a null terminated string value? */
applicationName,/* INPUT a null terminated string value? */
acsLevelReq, /* INPUT an integer ENUM value?*/
apiVer, /* INPUT a string value? */
sendQSize, /* INPUT an integer value? */
sendExtraBufs, /* INPUT an integer value? */
recvQSize, /* INPUT an integer value? */
recvExtraBufs, /* INPUT an integer value? */
privateData /* INPUT a null terminated string value? */);
=end
require 'dl'
csta=DL.dlopen('csta32.dll')
openStream=csta['acsOpenStream', 'IIIISSSSISIIIIS']
invokeIdType=2
invokeId=0
streamType=1
serverId="AVAYA#MERLIN#CSTA#MERLIN-CTI\000"
loginId="username\000"
passwd="password\000"
applicationName="CTI Test\000"
acsLevelReq=1
apiVer="TS2"
sendQSize=0
sendExtraBufs=0
recvQSize=0
recvExtraBufs=0
privateData="VERSION\000"

resultCode=openStream.call(invokeIdType,invokeId,streamType,serverId,loginId,passwd,applicationName,acsLevelReq,apiVer,sendQSize,sendExtraBufs,recvQSize,recvExtraBufs,privateData)
p resultCode[0]
----------------------------

The resultCode[0] entry returned -2, which according to the API means a
bad parameter was passed to the call. I double checked the expected
parameter data types and everything appears to be correct. the code
comments indicate what I _think_ the API expects to be passed to the
acsOpenStream method. This was going strictly against the TSAPI docs
that are public domain.
http://www.cs.cornell.edu/courses/cs519/1998fa/project/Doc/PBX/tsapi.pdf
is such an example.

Sigh....this is getting frustrating...
 
G

gregarican

gregarican said:
Sigh....this is getting frustrating...

I think I am getting closer. I know that the ENUM values being fed as
parameters are integer data types ('I') and some of the other numeric
values being fed are long data types ('L'). But the last few numeric
values being fed in are listed as being short data types (see my code
comments below). What do I put into the DL call method to indicate the
short data types for them? I couldn't find the corresponding flag for
them...
-----------------------------------------
=begin
TSAPI
acsOpenStream (acsHandle /* RETURN long value */
invokeIDType, /* INPUT integer ENUM value*/
invokeID, /* INPUT long value*/
streamType, /* INPUT integer ENUM value*/
serverID, /* INPUT null terminated string value*/
loginID, /* INPUT null terminated string value*/
passwd, /* INPUT null terminated string value*/
applicationName, /* INPUT null terminated string value*/
acsLevelReq, /* INPUT integer ENUM value (ignored)*/
apiVer, /* INPUT string value*/
sendQSize, /* INPUT short value */
sendExtraBufs, /* INPUT short value*/
recvQSize, /* INPUT short value*/
recvExtraBufs, /* INPUT short value*/
privateData /* INPUT null terminated string value */);
=end
 
T

Takaaki Tateishi

gregarican said:
values being fed are long data types ('L'). But the last few numeric
values being fed in are listed as being short data types (see my code
comments below). What do I put into the DL call method to indicate the
short data types for them?

"h" or "H" are for the short data types.

P.S.
Please refer the following resources if needed.
http://rubyforge.org/cgi-bin/viewcvs.cgi/dlcookbook/win32/?cvsroot=dlcookbook
http://raa.ruby-lang.org/project/rdl_en/
http://www.ruby-lang.org/cgi-bin/cv...e=text/plain;hideattic=0;only_with_tag=v1_8_3
 
G

gregarican

Takaaki said:
"h" or "H" are for the short data types.

Thanks. I found that in the DL docs
(http://www.ruby-doc.org/stdlib/libdoc/dl/rdoc/classes/DL/Types.html)
earlier today. I finally got this put together. The return type of the
method call is a long value. Previously I had used an integer value.
Then I had to make the call's first parameter (acsHandle) a pointer
value. Before I had totally left this parameter out. That's why the -2
return code was coming back. This translates to 'bad parameter.' Here's
my working code now:

---------------------------------------
require 'dl'
csta=DL.dlopen('csta32.dll')
openStream=csta['acsOpenStream', 'LPILISSSSISHHHHS']
acsHandle=[0].pack('L').to_ptr
invokeIdType=1
invokeId=0
streamType=1
serverId="AVAYA#MERLIN#CSTA#MERLIN-CTI\000"
loginId="username\000"
passwd="password\000"
applicationName="CTI Test\000"
acsLevelReq=1
apiVer="TS1-2\000"
sendQSize=0
sendExtraBufs=0
recvQSize=0
recvExtraBufs=0
privateData="VERSION\000"

resultCode=openStream.call(acsHandle,invokeIdType,invokeId,streamType,serverId,loginId,passwd,applicationName,acsLevelReq,apiVer,sendQSize,sendExtraBufs,recvQSize,
recvExtraBufs,privateData)
p resultCode[0]
--------------------------------------
Once I get all of this written I plan to share it with anyone who is
interested. It will be a working Ruby CTI envionment that works with
TSAPI-compliant elements. Not sure of the interest level, but I for one
will be glad to see it all come together :)

Thanks for your replies!
 

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

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,427
Latest member
HildredDic

Latest Threads

Top