Click to See Complete Forum and Search --> : Representing a "union" and "char*" in other languages (VBA) for .dll use
Eli Gassert
April 22nd, 2003, 08:47 AM
I hope my question says it all, but here's the deal.
I have a function inside a dll that takes a char* and a union'd data type. Is there anyway to represent these types in VB/VBA? I would assume so, and I would really hope so, otherwise I'm screwed :)
Excuse me if this isn't the best place to ask, but I figured C++ programmers would have more of an issue with this and know a little more on the subject than VB programmers, since the reversed situation isn't really a problem
Thanks guys!
Yves M
April 22nd, 2003, 09:06 AM
For the char*, you can simply use VB's String. It's important to know though that VB handles everything in wide characters internally, so in fact a VB String is just a BSTR. But when VB calls a function in an external DLL, it converts this BSTR automagically to a multibyte string (a char *). This is many times wanted, but sometimes not. In your case it shouldn't be a problem though.
For the union, things can get very very messy. This is because the byte-alignment of the union can be defined concretely in C/C++ and the developer of the DLL may have chosen to save a few extra bytes here and there. This said, there is a way to do this in VB, but I don't remember how.
If you are the programmer of this dll, then it might be better to wrap it up as a COM object, since that's easier to handle from VB and VBA.
Eli Gassert
April 22nd, 2003, 09:12 AM
Thanks for the reply!
Yeah i thought about wrapping it in a COM object, but that would require a lot of extra coding on my part (and I think more than the company would be willing for me to spend on it!).
Basically, this interface is a standard interface for a group of "helper" dlls. All of the dlls have the same function calls and prototypes, and it's up to the caller to decide which dll to make the call to. So I'd have to wrap all of that up in a COM object and make sure it's maintained as all the structures and passing params change. I doubt this modification is _that_ worth it.
As for issue #2, the ByRef problem. If it's passed in as a char *, I assumed I would pass in my string as ByRef, however I'm getting junk on the otherside. Oddly, when I have a char[SIZE] array, and I pass the following string ByRef, it works:
dim MyString As String * SIZE ' defined size for a string...
Oh well, i'll keep playing with that. The union thing is what's gonna end up killing me on this one though, I'm sure I'll get string working quickly enough :)
thanks again! If anyone else has any thoughts or suggestions please reply, cuz I'm clueless here :confused:
Yves M
April 22nd, 2003, 11:09 AM
When passing a string from VB to the dll, you should pass it byval, not byref. Otherwise you will get a pointer to a char *, so a char ** and that's not what you want.
If you only pass the union from VB to the dll, then things might be easier if you just declare different Types for the different forms the union can take. What is the exact signature of the dll functions ? Is the union passed by pointer ?
Eli Gassert
April 22nd, 2003, 12:58 PM
WORD CALLBACK spl_ProcessData (
SPL_HANDLE hProcess,
const LPFILESPEC lpfsDataFile,
LONG lNumXAxisPts,
DATA_UNION duIndependentConvert,
DATAID didIndependentType,
const FS_DATABUFFER_PTR hpIndependentData,
DATA_UNION duDependentConvert,
DATAID didDependentType,
const FS_DATABUFFER_PTR hpDependentData,
const FS_PATTERNDEF FAR * lpPatternDesc,
DATA_UNION FAR * lpduTransformedConvert,
DATAID FAR * lpdidTransformedType,
FS_DATABUFFER_PTR hpTransformed,
FS_DATABUFFER_PTR hpOutputData,
STATUS_DEF FAR * lpFncStatus)
most of those types are just typedefs for common types, SPL_HANDLE is a handle (long) DATA_UNION is the type that's killin me now -- as you can see it's used both ByVal and ByRef. FS_DATABUFFER_PTR is char*, and STATUS_DEF is a user defined struct; everything else is just a long or int w/a typedef/#define.
I did a sizeof on my DATA_UNION union, and it's 8 bytes. I was thinking about trying to send in a byte array in that place, but I'm failing with that method -- I keep getting permission denied errors in VC++6.0 debugger on excel.exe
dim Arr(7) As Byte
Arr(0) = 0
...
...
I forget how I passed in Arr, but I think it was ByRef, because ByVal was coming through as invalid or something in the VBA compiler.
thanks for your help!
Yves M
April 22nd, 2003, 01:28 PM
Don't arrays start at 1 in VBA like in VB ?
But the basic problem I see is that VB passes user-defined types or arrays as pointers by default. I'm not quite sure how you would actually pass it by value :/ But maybe the people on the VB forum might have a better idea about this.
Eli Gassert
April 22nd, 2003, 01:39 PM
Ok I'll search around, thanks bud!
mwilliamson
April 22nd, 2003, 03:47 PM
Originally posted by Yves M
Don't arrays start at 1 in VBA like in VB ?
But the basic problem I see is that VB passes user-defined types or arrays as pointers by default. I'm not quite sure how you would actually pass it by value :/ But maybe the people on the VB forum might have a better idea about this.
VB arrays start at 0, but when you create them you specify the maximum index, not the number of elements. There is actually a way to create a vb array that starts at x and ends at y. Why VB programmers can't figure out the max index is beyond me ;)
Eli Gassert
April 22nd, 2003, 05:57 PM
Hey I did it correctly :)
You can do:
redim Array(1 to Whatever) if you want one based, otherwise it's redim Array(0 to whatever) by default, so yeah you define the UBound... it's easy, but annoying! I hate VB ;)
Eli Gassert
April 23rd, 2003, 08:25 AM
I just wanted to say thanks to those who helped out. I found a solution after a few hints and tricks from the guys in the VB forum.
For those interested, here is the link to the thread with the solution. For now it'll work because the union is 8 bytes long, so I pass in a double ByVal and all is good, but if that thing ever increases in size I dunno what to do. Oh well I'm only here for a 6 month internship, hopefully I'll be gone by that time ;)
http://www.codeguru.com/forum/showthread.php?s=&postid=723167#post723167
thanks again!
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.