A customer asks:
I’m using a third party COM server dll with my VFP8 application.
One of its methods requires a structure as a parameter.
It seems to me that unlike with dlls, where you can trick VFP into substituting a character string for a structure in a DECLARE statement,
this can’t be done with a COM object, where you can’t change the data type of parameter within VFP.
I get Error 11, Function argument value, type, or count is invalid, when I call the COM object’s method.
The required data structure contains a LONG and a SHORT.
I tried building up an integer value with both values concatenated in it, but when the value is big enough, it looks like it becomes a negative number
to VFP, and this too causes an Error 11.
Is there a way to do this?
The answer is obviously yes there’s a way, but it may be cumbersome and will require some investigation.
A simple solution would be to create an intermediate DLL (COM or not) which could be used to talk to the 3rd party DLL.
Non automation compatible types are tricky. Clients that use COM objects can be in
1. the same process, same thread,
2. the same process, different thread,
3. a different processs,
4. a different machine.
All but the first require marshalling of parameters between the client and the object. COM allows clients to call objects the same way in each of these cases. Marshalling of a simple integer is trivial: just put the integer on the calling stack of the target object. A string is much more complex. It needs to be Unicode and space has to be allocated for the string available to the target object, and the rules about who needs to free the string need to be followed. Passing an object is even trickier: a proxy/stub needs to be set up (in all but the 1st case) in each of the client and object’s threads. Using Automation compatible types, a standard proxy/stub can be used.
Using the DECLARE DLL command, users can call DLL exported functions like much of the Win32 API. If a function requires a structure as a parameter, then the user can create a string (which is just a memory block) and use that as a parameter. No marshalling or Unicode conversion takes place.
It’s hard to come up with a solution without knowing details of the 3rd party DLL, such as does it support dual interfaces? Does the structure contain only a LONG and a SHORT? Does it have a proxy/stub DLL ?
Other possible solutions:
- Perhaps it can be called via early binding via the GetInterface or the CreateObjectEx functions.
- Perhaps use an array of bytes
- Check out the COMARRAY function