logo       

Re: Passing byte arrays into C functions: msg#00013

windows.devel.jawin

Subject: Re: Passing byte arrays into C functions

Hi Alex,

I was mostly involved with the stub generation from TypeLib's. In the
area of marshaling I'm not the expert. We have a group of good guys but
we are all busy. We are talking about redoing the marshaling at some
point. If I get inspired I may sit down for a week and write a start
for new marshaling( Java 1.4 and above).

Some of the things your are talking about are of interest. If you have
a sourceforge account I would be happy to turn it on for Jawin and work
with you on your projects. I need to get active again with Jawin; it's
just that I'm doing more things with linux and one of my other pet
projects that is more interesting and has more potential. However there
has been some good administration of the project by Morten and
contribution from others that I would like to make more valuable by
making another rewrite of Jawin marshaling and add in event handling as
pointed out by Cyril. There is a great set of very busy folks involved
with Jawin; just need to make it worth it by refactoring marshaling:-)
A better set of examples would be very good. We have talked of ways to
make stub generation for non-COM dll's but haven't found a complete way
to achieve it.

What is your project(s) time line(s)?

Regards,

Roger


Alex Kotchnev wrote:

I give up - I must be stupid.. I have been trying to figure out how to
run something as simple as GetComputerNameW in kernel32.dll.. and I keep
getting horrible errors - Access violations, running out of memory, etc.

I am going to explain my thinking step by step, you never know, it might
help me figure out exactly what I'm doing wrong.

Well, in the tradition of answering your own questions, this is exactly
what happenned : after trying to get this right for the last many hours,
and after getting a hole bunch of errors ranging from memory access
violations (e.g. when I was passing the second param as a regular int (an
I instruction) , and no as a pointer to an int (a P4 instruction)),
running out of memory, "filename too long", I finally got it. Another
error that I didn't figure out for the longest time was that I was
creating a String with the length of 300, and then I wrote that string to
the output stream (instead of writing an array of bytes with the length of
300, I was writing an unicode string with the length of 300 - which in
bytes is probably 4 times longer) and then passing instructions that the
byte array was 300 bytes long . I realize that I might be making an ass
out of myself, but this could be helpful for some other newbie. Also, I
might try to put together something like the mini-program below, and then
provide them to the project as documentation.



Ok, this is the description of the function:

BOOL GetComputerName(
LPTSTR lpBuffer,
LPDWORD lpnSize
);

Parameters
lpBuffer
[out] Pointer to a buffer that receives a null-terminated string
containing the computer name or the cluster virtual server name. The
buffer size should be large enough to contain MAX_COMPUTERNAME_LENGTH + 1
characters.
lpnSize
[in, out] On input, specifies the size of the buffer, in TCHARs. On
output, the number of TCHARs copied to the destination buffer, not
including the terminating null character.
If the buffer is too small, the function fails and GetLastError returns
ERROR_BUFFER_OVERFLOW. The lpnSize parameter specifies the size of the
buffer required, not including the terminating null character.

So, in order to get things right, this is what I do (in Jython again, but
it should be easy to folow):

from org.jawin import *
from org.jawin.io import *
from org.jawin.marshal import *
from com.divintech.testing import *
from java.io import *

getCompName = FuncPtr("kernel32.dll","GetComputerNameW")

nbs = NakedByteStream();
leos = LittleEndianOutputStream(nbs);

# This creates a buffer, 300 bytes long writing 1 in each byte
for i in range(300):
leos.writeByte(1)

#write out the length of the buffer
leos.writeInt(300)

# It doesn't seem like I can fit this method call into any of the
"shortcut" invokes, so I go with the long one

# this instruction doesn't work - I guess because the parameter of
GetComputerName is an int pointer, and not an int
# this part of the instructions, for me it means that I am passing a byte
array with a length of 300 and a 4 byte out param - it would have been ok
if the 2nd param of the function was taking an int, and not a
# pointer to int
# instructions = "P300A"

#therefore, the correct instruction is, because the P4 basically says -
take the address this, and put the address to the native method -
essentially passing a pointer to the native method.

instructions = "P300P4"

# the return method is an int so then:
instructions = instructions + ":I:"

# at the end, we have 2 out parameter - the first is the buffer of length
300 and then an int of length 4
instructions = instructions + "n300n4"

# then, the function call is
# the first argument is the instruction string that I composed.
# the second argument is the stack size - 304 - since we passed the whole
buffer on the stack ??? - is this correct ?
# the remaining arguments really don't need an explanation
res = getCompName.invoke(instructions, 304, nbs, None,
ReturnFlags.CHECK_FALSE)

# now, construct the inputstream over the result
leis = LittleEndianInputStream(ByteArrayInputStream(res))

# read the return value - at this point I'm not using it, it gets checked
by the ReturnFlags param
b1 = leis.readInt()

# then, read the string , using the suggested length , which gives us the
correct value
## Da-Da-a-a, this is the actual result, which is correct without any
errors.
leis.readUnicodeSz(300)

# Finally , read in how many characters were put into the buffer
r2 = leis.readInt()





Regards,

Alex Kotchnev
Developer / Systems Analyst
Diversified Information Technologies

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CONFIDENTIALITY NOTICE: If you have received this e-mail in error, please
immediately notify the sender by e-mail at the address shown. This e-mail
transmission may contain confidential information. This information is
intended only for the use of the individual(s) or entity to whom it is
intended even if addressed incorrectly. Please delete it from your files
if you are not the intended recipient. Thank you for your compliance.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++






<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise