Fliptronics

Visual Basic (V3) and passing arrays to your own DLL

Home Page
Tutorials
HW Products
CAE/SW Products
Tips & Tricks
Digital System Design
Links
Art Gallery
About Fliptronics

(Vintage June 1995. )

Someone wrote:

VB deals with arrays totally different than C deals w/arrays. VB arrays are not neatly stored in contiguous memory. As a result, you either have to pass a VB array one string at a time, or your C DLL has to access the VB array on VB's terms.

Jeff Fields responded:

Where is this coming from? I use Borland C++ 4.02 to write my DLL's. I haven't had to rewrite any of my code to compensate for any difference in the VB handles arrays. Pass the first element of the array from VB to the DLL and you're set. I have a DLL that contains most of the various sorting routines--bubble(3 variations), shaker, selection, insertion, quicksort, merge sort and a few others. Never had any problems!

Someone wrote:

The Control Development Kit (CDK), which is packaged with VB 3.0 Professional Edition, includes APIs that can be used to update a VB array from within a C DLL. This is the only way, that I have found, to access a VB array from within C. Good luck, and if you find a better way please send it along. Thanks.

Philip Freidin (me) responded:

The reason you haven't had problems is because your arrays haven't exceeded 64K bytes :-)

In arrays that require > 64Kb, you will discover that about 8 or 16 bytes before the first 64K boundary, the data you fetch with a far pointer in your DLL is not the data that VB put after the data in the prior array element. A real pain.

Jeff Fields responded:

Is this a MSVC++ or VB limitation? I have sorted some fairly large arrays, but you are correct I probably haven't sorted any >64 kb.

Philip Freidin (me) responded:

I believe the problem is in the way that VB stores the arrays. It keeps a header around to help it do its access. when you pass an array to a DLL, you do it by not using the ByVal, and passing the first element. What gets sent is the address, which you then use as a pointer to the rest of the array. This seems to break if the array exceeds 64K. I don't know if it breaks because the data is not stored in contiguous locations, or if VC++ gets confused with an array that exceeds 64KB, but the first element is not in the first location of the segment. Here is what I had: an array of LONGs, 2048 * 18, which is 4096 LONGS longer than 128KB. In VB land I could read and write the whole array with no problems. In VC++ land (in my DLL) I passed it as arrayname(0,0). I could read and write all of it reliably except for the 4 longs at the end of 8th block of 2048. I.E. the 16 bytes at the end of the first 64KB. This took me FOREVER to track down. I solved the problem by a real messy solution: I now have 18 different arrays each 2048 LONGs long. I now have to call my DLL 18 times. I am sure there is a better solution, and it is probably in the VB API library, where I suspect there are functions that you pass indexes to, and it figures out how to get the data for you. I didn't have time to look it up, as I had other problems to pursue, and my kludge fix worked. If you find out how to do this cleanly, PLEASE mail me.


Copyright © 1998, 1999, 2000, 2001, 2002  by Fliptronics. All rights reserved.
Fliptronics, Sunnyvale, CA 94086-7629, USA
TEL: 408-737-0295, E-mail: philip@fliptronics.com