Re: VB6 generates faulty exe code: UDT passed from VB6 to DLL
- From: "Trevor Short" <trevors@xxxxxxxxxxxxxxxxxxxx>
- Date: Wed, 6 Apr 2005 11:49:37 -0700
Hi Norman,
I've taken a look at the repro you describe on this thread. Upon
investigation, I notice that the C source code contains:
SomeStrLen = strlen((char*)pAnything);
In your code, pAnything is being used as a pointer to the string the VB UDT
passed to the C dll. The C dll assumes that the string has a null
terminator. However, VB strings and C strings are different in that VB
strings are not terminated with a null char. When the above line of code is
called on a pointer to memory without a null terminator it will read past
what you might consider to be the end of the string into random memory until
it finds one.
It's possible that your customer's program might be making the same
assumption. This may result in crashes and other seemingly odd behavior.
There are two questions you had in the thread:
1) Why is there padding in the temp location of the UDT when passed to the C
dll? Each element in a VB UDT is byte aligned to 4 bytes, but C++ objects
are aligned to 8 bytes. There's a bit of explicit marshalling you need to do
to ensure that the memory translates well. The following KB article
discusses this a little bit: http://support.microsoft.com/kb/171583/EN-US/
2) Why are Len() and LenB() different in how they count the bytes in a UDT?
Again, there is a good KB article that discusses this:
http://support.microsoft.com/default.aspx?scid=kb;en-us;137729
I'm still interested to understand how this problem was uncovered after 8
years of running smoothly. Was there a transition from VB4 to VB6?
Trevor Short
Microsoft Visual Basic Development
"Norman Diamond" <ndiamond@xxxxxxxxxxxxx> wrote in message
news:91EC66EE-3230-4914-83DA-6E8A9700F1DF@xxxxxxxxxxxxxxxx
> "Ken Halter" wrote:
>> "Norman Diamond" wrote...
>> >A program has a bunch of User Defined Types
>> > and a bunch of variables declared with those types,
>> > and sometimes passes those variables to functions
>> > defined in a DLL. The program uses Declare
>> > statements for the DLL functions, and the relevant
>> > parameters have ByRef and As Any. The program
>> > also calls VB's builtin function Len() on those
>>
>> Use LenB....
>
> The original posting said why I cannot. The actual length
> of the temporary is intermediate between what Len() says
> and what LenB() says. If I pass the result from LenB() to
> the length parameter of the DLL function, then the DLL will
> walk all over other storage that happens to be located near
> the temporary. And I think you already knew that without
> needing to be told.
>
>> HOWTO: Pass Array of UDTs with Variable Length Strings to C/C++
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;194609
>
> Useless. These are fixed-length strings stored inside the
> the UDT without extra pointers (which is why the sample
> I posted is named nonBSTRcheck), each UDT being
> passed is a single UDT not an array, and I cannot barge in
> and tell the customer to redesign 8 years of accumulated
> code to operate with a type library instead of Declare
> statements.
>
>> INFO: Visual Basic Requirements for Exported DLL Functions
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;142840
>
> As far as I can tell, that is conformed to both by the
> customer's program and my additions.
>
>> How to Pass a String or String Arrays Between VB and a C DLL
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;118643
>
> Useless. I do believe that standalone strings work. The
> problem is fixed-length strings contained inside UDTs.
>
>> HOWTO: Pass a String Between Visual Basic and Your C DLL
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;187912
>
> Didn't I just answer that? Oh, it's a different KB number
> with the same contents. OK. Same answer.
>
>> HOWTO: Write C DLLs and Call Them from Visual Basic
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;106553
>
> Well, my sample DLL uses MFC so I don't have to
> define LibMain myself, but otherwise I think both the
> customer's code and my additions conform to this.
>
>> How to Pass Numeric Variables to a C DLL
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;94960
>
> I admit that I didn't decorate my Basic variable names
> in the style of x% or x&
> Nonetheless each field of the UDT is declared with its
> exact type.
> (By the way did you read that KB article? Microsoft
> didn't say x& they really said x& )
>
>> How to Pass & Return Unsigned Integers to DLLs from VB
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;112673
>
> No problem with these.
>
>> If none of that helps, I'll find someone to look at your code (assuming
>> that
>> you can post some)
>
> I did. As my original posting said,
> The test can be downloaded from:
> http://www.geocities.jp/hitotsubishi/nonBSTRcheck.zip
> (That URL is case-sensitive, 4 capital letters, sorry.)
>
> By the way, in this posting, every place where I quoted
> URLs that you wrote, there are invisible hyphens that
> get copied and pasted so IE can't open them properly.
> I didn't really mind deleting those hyphens when
> copying and pasting from your article (I don't know
> how they got there without being seen) but am more
> irritated that they still happen when copying and pasting
> from my article (I still don't know how they got there
> without being seen). Copying and pasting my URL
> http://www.geocities.jp/hitotsubishi/nonBSTRcheck.zip
> properly fetches a download of my sample.
.
- Follow-Ups:
- Re: VB6 generates faulty exe code: UDT passed from VB6 to DLL
- From: Norman Diamond
- Re: VB6 generates faulty exe code: UDT passed from VB6 to DLL
- Prev by Date: Re: vb Application is generating Object variable or With clause variable not set
- Next by Date: Re: VB6 generates faulty exe code: UDT passed from VB6 to DLL
- Previous by thread: How to code delete page breaks?
- Next by thread: Re: VB6 generates faulty exe code: UDT passed from VB6 to DLL
- Index(es):
Relevant Pages
|