BUG: "Too Many Local, Nonstatic Variables" Error Message (179140)
The information in this article applies to:
- Microsoft Visual Basic Learning Edition for Windows 5.0
- Microsoft Visual Basic Learning Edition for Windows 6.0
- Microsoft Visual Basic Professional Edition for Windows 5.0
- Microsoft Visual Basic Professional Edition for Windows 6.0
- Microsoft Visual Basic Enterprise Edition for Windows 5.0
- Microsoft Visual Basic Enterprise Edition for Windows 6.0
This article was previously published under Q179140 SYMPTOMS
When compiling an application that calls functions or subroutines in a DLL
and that passes large User Defined Types to the DLL, you may receive the
following error message:
Too many local, nonstatic variables
CAUSE
The above error is the result of a bug in the Visual Basic compiler when
allocating memory for passing User Defined Types (UDTs) to functions or
subroutines in DLLs. The error may occur when this amount exceeds
approximately 64KB.
RESOLUTION
You can work around this problem by changing the way that such UDTs are
passed to the DLL. When you pass a UDT to a DLL, you are actually passing a
pointer to the first memory location of the UDT. Another way to pass this
pointer is by copying the UDT to a Byte array and passing the first element
of the Byte array by reference. NOTE: You will need to calculate the size of this Byte array manually,
taking into consideration the issues relating to byte-alignment.
For more information regarding byte-alignment, refer to Section 6 of the
VB5DLL.DOC document located in the Tools\Docs folder of the Visual Basic
CD-ROM.
Because the Visual Basic run-time library converts the strings from UNICODE
to ANSI when using the CopyMemory function below, you should only allocate
1 byte for each character in your fixed-length strings.
Assuming you have the following UDT and Declare statement for your DLL:
Type LargeUDT
nAge as Integer
sName As String * 4000
lMiles as Long
End Type
Dim aLargeUDT As LargeUDT
Declare Sub MySub Lib "MYDLL.DLL" (x As LargeUDT)
Follow these steps to implement a workaround to the problem: - Manually calculate the size necessary for the UDT:
Const UDT_SIZE = 4008
- Create the following Declare within your application (a Windows A
function to copy memory from one location to another):
Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" ( _
lpvDest as Any, lpvSource as Any, ByVal cbCopy as Long)
- Change the declaration of the subroutine within the DLL to accept 1 byte
by reference in place of the UDT argument:
Declare Sub MySub Lib "MYDLL.DLL" (x As Byte)
- Create a Byte Array to store the User Defined Type. Re-dimension the UDT
using the manually-calculated constant UDT_SIZE in step 1:
Dim ab() as byte
Redim ab(UDT_SIZE)
- When calling the subroutine in the DLL, you must first call CopyMemory
to copy the UDT into the Byte array. Next, call the subroutine, passing
it the first element of the Byte array. Finally, call CopyMemory again
to copy the Byte array back into the UDT:
CopyMemory ab(0), aLargeUDT, UDT_SIZE
MySub ab(0)
CopyMemory aLargeUDT, ab(0), UDT_SIZE
STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed
at the beginning of this article. We are researching this bug and will post
new information here in the Microsoft Knowledge Base as it becomes
available.
REFERENCES
For additional information on calling subroutines and functions in DLLs,
please see the following document:
VB5DLL.DOC, Visual Basic 5 CD-ROM (Professional and Enterprise Editions
Only), in the following folder ...\TOOLS\DOCS\.
Modification Type: | Major | Last Reviewed: | 5/13/2003 |
---|
Keywords: | kbBug kbpending KB179140 |
---|
|