Re: Passing byte arrays into C functions

Roger I Martin PhD <[email protected]>
Newsgroups gmane.comp.windows.devel.jawin
Message-ID <[email protected]>
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.
>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.