(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.
|