Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

VB Activex dll in VC++ with array parameter

224 views
Skip to first unread message

Andrea Visinoni

unread,
Mar 2, 2011, 10:35:02 AM3/2/11
to
I'm trying to use a VB Activex dll in VC++ 6.0 following this
procedure:
http://support.microsoft.com/kb/194873/en-us

i successfully create my idispatch class but some members are not
being correctly created due to:

method 'GetReading' not emitted because of invalid return type or
parameter type

this happen with all the methods with array as parameters, the only
thing i know about this method is that in VB is like this:

GetReading (sSerNum, By Ref dRdgArray(0 to 3))

so i'ts an array of double, i want to manually add it.

Any hints?

Andrea Visinoni

unread,
Mar 3, 2011, 3:54:08 AM3/3/11
to

I did some steps...

this is the prototype of the method as seen in ole/com object viewer:

[id(0x60030002)]
HRESULT FindQpods(
[in, out] SAFEARRAY(BSTR)* SNArray,
[out, retval] long* );

info by docs are: FindQpods (By Ref sSNArray(0 to 32)) [=lRtnVal]

this is how i'm trying to implement it into my dispatch class:

long _cQPod::FindQpods(SAFEARRAY *array)
{
VARIANT pVarOut;
VariantInit(&pVarOut);
pVarOut.vt = VT_ARRAY|VT_BSTR|VT_BYREF;
pVarOut.parray = array;

long result;
static BYTE parms[] = VTS_PVARIANT;//VTS_VARIANT;

InvokeHelper(0x60030002, DISPATCH_METHOD, VT_I4, (void*)&result,
parms, array);
return result;
}

but i still get: Warning: constructing COleException, scode =
DISP_E_TYPEMISMATCH ($80020005).

Andrea Visinoni

unread,
Mar 3, 2011, 3:57:57 AM3/3/11
to
On 3 Mar, 09:54, Andrea Visinoni <andrea.visin...@gmail.com> wrote:
> long _cQPod::FindQpods(SAFEARRAY *array)
> {
>     VARIANT pVarOut;
>     VariantInit(&pVarOut);
>     pVarOut.vt = VT_ARRAY|VT_BSTR|VT_BYREF;
>     pVarOut.parray = array;
>
>     long result;
>     static BYTE parms[] = VTS_PVARIANT;//VTS_VARIANT;
>
>     InvokeHelper(0x60030002, DISPATCH_METHOD, VT_I4, (void*)&result,
> parms, pVarOut);
>     return result;
>
> }

there was an error, but still the same warning

Joseph M. Newcomer

unread,
Mar 3, 2011, 11:25:57 AM3/3/11
to
See below...
On Thu, 3 Mar 2011 00:54:08 -0800 (PST), Andrea Visinoni <andrea....@gmail.com>
wrote:

>On 2 Mar, 16:35, Andrea Visinoni <andrea.visin...@gmail.com> wrote:
>> I'm trying to use a VB Activex dll in VC++ 6.0 following this
>> procedure:http://support.microsoft.com/kb/194873/en-us
>>
>> i successfully create my idispatch class but some members are not
>> being correctly created due to:
>>
>> method 'GetReading' not emitted because of invalid return type or
>> parameter type
>>
>> this happen with all the methods with array as parameters, the only
>> thing i know about this method is that in VB is like this:
>>
>> GetReading (sSerNum, By Ref dRdgArray(0 to 3))
>>
>> so i'ts an array of double, i want to manually add it.
>>
>> Any hints?
>
>I did some steps...
>
>this is the prototype of the method as seen in ole/com object viewer:
>
>[id(0x60030002)]
> HRESULT FindQpods(
> [in, out] SAFEARRAY(BSTR)* SNArray,
> [out, retval] long* );
>
>info by docs are: FindQpods (By Ref sSNArray(0 to 32)) [=lRtnVal]
>
>this is how i'm trying to implement it into my dispatch class:
>
>long _cQPod::FindQpods(SAFEARRAY *array)
>{
> VARIANT pVarOut;

****
By convention, a 'p' prefix means it is a pointer. But it isn't. It is a VARIANT, not a
PVARIANT. Which I suspect is the type you intended. So why the 'p' prefix?
****


> VariantInit(&pVarOut);
> pVarOut.vt = VT_ARRAY|VT_BSTR|VT_BYREF;
> pVarOut.parray = array;

****
And where, exactly, ire these two variables used in the InvokeHelper? You give the
parameter type as VTS_VARIANT, and point to the array, but these other values you compute
do not appear anywhere in the list; instead, you pass the raw 'array' value. Wouldn't it
make more sense to pass &pVarOut as the last argument?


>
> long result;
> static BYTE parms[] = VTS_PVARIANT;//VTS_VARIANT;

*****
There is something completely deadly wrong about putting a static variable inside a
function definition. Do not ever do this. If a tool did this, it is badly broken. Or,
if it is a constant, why doesn't it say
const static BYTE parms[] = VTS_PVARIANT;
Note that you are telling it that you are passing a pointer-to-a-variant as the result
type, but what you pass it is a SAFEARRAY *, not a PVARIANT.

What is specified in your typelib for this function? Not in VB, but in the typelib
itself? I can't read VB code (I once wrote a VB subroutine about 20 years ago so I can't
comment on the syntax) so I have no idea how that translates to a typelib definition.
*****


>
> InvokeHelper(0x60030002, DISPATCH_METHOD, VT_I4, (void*)&result,
>parms, array);

****
I suspect this should be
InvokeHelper(...as above.., parms, &pVarOut);
****


> return result;
>}
>
>but i still get: Warning: constructing COleException, scode =
>DISP_E_TYPEMISMATCH ($80020005).

****
Where do you get this warning? What line produces it? Which tool? Does it really put
that $ in there?
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Andrea Visinoni

unread,
Mar 4, 2011, 3:18:22 AM3/4/11
to
The problem is that this is DLL come from a device and the only thing
i have is a useless pdf with
this prototype:

FindQpods (By Ref sSNArray(0 to 32)) [=lRtnVal]

and this info from a IDL file generated by OLE viewer (analyzing the
DLL)

[id(0x60030002)]
HRESULT FindQpods(
[in, out] SAFEARRAY(BSTR)* SNArray,
[out, retval] long* );

the automatic procedure of VC++ 6.0 creating an IDispatch class to
interface to the DLL, failed on all the methods having arrays as
parameter.
so the truth is i really don't know how to achieve the creation of
this missing method.

yes passing "array" var to the Invokehelper was my mistake, but i
still have the error.

any hints are really welcome :)

On 3 Mar, 17:25, Joseph M. Newcomer <newco...@flounder.com> wrote:
> See below...

> On Thu, 3 Mar 2011 00:54:08 -0800 (PST), Andrea Visinoni <andrea.visin...@gmail.com>

> email: newco...@flounder.com

Goran

unread,
Mar 4, 2011, 4:29:19 AM3/4/11
to
On Mar 4, 9:18 am, Andrea Visinoni <andrea.visin...@gmail.com> wrote:
> The problem is that this is DLL come from a device and the only thing
> i have is a useless pdf with
> this prototype:
> FindQpods (By Ref sSNArray(0 to 32)) [=lRtnVal]
>
> and this info from a IDL file generated by OLE viewer (analyzing the
> DLL)
>
> [id(0x60030002)]
>         HRESULT FindQpods(
>                         [in, out] SAFEARRAY(BSTR)* SNArray,
>                         [out, retval] long* );
>
> the automatic procedure of VC++ 6.0 creating an IDispatch class to
> interface to the DLL, failed on all the methods having arrays as
> parameter.

You might try using #import, then call the method directly. E.g.

#import "yourserver.tlb" // or dll or exe

yourserver::IYourObjectPtr
p(yourClassWizardGeneratedObject.m_lpDispatch);
SAFEARRAY a = PrepareSafearrayWithStringsInIt();// (educated guess on
what FindQPods need)
long count;
p->FindQPods(&a, &count);

Goran.

Andrea Visinoni

unread,
Mar 4, 2011, 4:46:39 AM3/4/11
to
I think it's more or less like the second example in:
http://support.microsoft.com/kb/194873/en-us

but it's still not clear to me what are these:

yourserver::IYourObjectPtr
p(yourClassWizardGeneratedObject.m_lpDispatch);

Andrea Visinoni

unread,
Mar 4, 2011, 6:13:15 AM3/4/11
to
this seems to work correctly (unluckily i still don't have the device
to properly try)

CoInitialize(NULL);

SAFEARRAY *psaOut = SafeArrayCreateVector(VT_BSTR, 0, 32);

try
{
HRESULT res;

Qpod_DLL::_cQPodPtr ptr;

res = ptr.CreateInstance("Qpod_DLL.cQPod");

if (res == S_OK)
long ret = ptr->FindQpods(&psaOut);
}
catch(_com_error &e)
{
TRACE1("Err: %s\n", e.Description());
}

CoUninitialize();

i only have this exception:
First-chance exception in activex.exe (KERNEL32.DLL): 0xC000008F:
Float Inexact Result.

Nobody

unread,
Mar 5, 2011, 12:27:30 AM3/5/11
to
"Andrea Visinoni" <andrea....@gmail.com> wrote in message
news:a7da0a79-4d13-4e74...@y14g2000vbb.googlegroups.com...

> i only have this exception:
> First-chance exception in activex.exe (KERNEL32.DLL): 0xC000008F:
> Float Inexact Result.

INFO: Visual Basic Uses Exception Code 0xC000008F as Internal Exception Code
http://support.microsoft.com/default.aspx?scid=kb;en-us;232829


0 new messages