Microsoft KB Archive/179140

= BUG: "Too Many Local, Nonstatic Variables" Error Message =

Article ID: 179140

Article Last Modified on 5/13/2003

-

APPLIES TO


 * Microsoft Visual Basic 5.0 Learning Edition
 * Microsoft Visual Basic 6.0 Learning Edition
 * Microsoft Visual Basic 5.0 Professional Edition
 * Microsoft Visual Basic 6.0 Professional Edition
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition

-



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 </ol>

<div class="status_section">

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.

<div class="moreinformation_section">

Steps to Reproduce Behavior
<ol> Start a new Standard EXE project. Form1 is created by default.</li>  Paste the following code into the code window of the form. Note that there are nine calls to MySub and the ninth one is commented out: Option Explicit Private Type LargeUDT a As String * 4000 End Type

Dim aLargeUDT As LargeUDT

Private Declare Sub MySub Lib "MYDLL.DLL" (x As LargeUDT)

Private Sub Form_Load MySub aLargeUDT MySub aLargeUDT MySub aLargeUDT MySub aLargeUDT MySub aLargeUDT

MySub aLargeUDT MySub aLargeUDT MySub aLargeUDT 'MySub aLargeUDT End Sub </li> Compile the application by selecting "Make Project1.exe" from the File Menu. It should compile as expected, and create the Project1.exe file.</li> Uncomment the last call to MySub by removing the apostrophe at the start of the line.</li> Compile the application again and note that it now fails with the error, "Too many local, nonstatic variables."</li></ol>

<div class="references_section">