LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

ActiveX Control wrapper function returning incorrectly

Solved!
Go to solution

Hi all,

 

Thanks for taking the time to read and (hopefully) reply.

 

I'm working with an instrument driver I created from an ActiveX control using the ActiveX Controller Wizard.  However, I have a function that won't return one of it's arguments but it will return the other.  See below.

 

The objective is to open up a device called the EV2300.  GetFreeBoards() should return the number of devices (boards) found and the names of the boards.  It finds and returns the number of devices fine (2 if two devices are connected, 1 if one device connected and 0 when no devices are connected) but where it fails is returning the names.  The character array passed in as reference just remains empty and no errors are reported.

char msgStr[256]; char *BrdName; ERRORINFO error; CAObjHandle EV2300_Handle; int returnVal; long nBrdsFound = 0; mainpanel = LoadPanel (0, "TE_User_Interface.uir", MAIN_PANEL); GetObjHandleFromActiveXCtrl (mainpanel, MAIN_PANEL_BQ80XRW, &EV2300_Handle); BrdName = msgStr; returnVal = BQ_EV2300_GetFreeBoards (EV2300_Handle, &error, 16, &nBrdsFound, &BrdName);

 

The wrapper function generated by the wizard:

HRESULT CVIFUNC BQ_EV2300_GetFreeBoards (CAObjHandle objectHandle,
ERRORINFO *errorInfo,
long nNumBrdsToGet, long *nNumBrds,
char **listBrdNames)
{
HRESULT __result = S_OK;
unsigned int __paramTypes[] = {CAVT_LONG, CAVT_LONG | CAVT_BYREFI,
CAVT_CSTRING | CAVT_BYREFI};

__result = CA_MethodInvokeEx (objectHandle, errorInfo, &BQ_IID_EV2300_,
0x7, CAVT_EMPTY, NULL, 3, __paramTypes,
nNumBrdsToGet, nNumBrds, listBrdNames);

return __result;
}

 

Using the same ActiveX controller and hardware set-up in VB6 works perfectly: the name of the EV2300 is returned and I can go on to use it in other functions:

 

Dim Bq80xRW1 As Bq80xRW Dim BrdName As String Dim nBrdsFound As Long Bq80xRW1.GetFreeBoards 16, nBrdsFound, BrdName

 

Any ideas what I could be doing wrong?

 

 

0 Kudos
Message 1 of 12
(5,836 Views)

The most probable reason is that the method invoked expects to receive a pointer to a string, while you are passing a pointer to a pointer of chars which has not been initialized. Visual basic passes all parameters by reference, unless the ByVal keyword is used, so it passes the address of a string (properly dimensioned variable). The documentation of the device driver should inform you whether the function allocates memory for you or not but it probably won't.

 

If this is true, your code will probably work if you declare

char BrdName[512];

Message Edited by Roberto Bozzolo on 10-24-2009 09:36 AM


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 12
(5,826 Views)

I tried your suggestion and recieved this error message when declaring char BrdName[256]:

 

"Type error in argument 5 to `BQ_EV2300_GetFreeBoards'; found 'pointer to array 256 of char' expected 'pointer to pointer to char'."
 

 

LabWindows/CVI wants a pointer to a pointer to char so that's what I've been giving it but I've tried a number of different variations and still nothing. 

 

According to the wrapper code the function expects a CAVT_CSTRING (from the Help:  "char * (null-termineated string)") passed by reference (CAVT_BYREFI, "Pointer to data type.  Input-only parameter you pass by reference.  Defined as CAVT_BYREF | CAVT_IN.").

 

HRESULT CVIFUNC BQ_EV2300_GetFreeBoards (CAObjHandle objectHandle,
ERRORINFO *errorInfo,
long nNumBrdsToGet, long *nNumBrds,
char **listBrdNames)
{
HRESULT __result = S_OK;
unsigned int __paramTypes[] = {CAVT_LONG, CAVT_LONG | CAVT_BYREFI,
CAVT_CSTRING | CAVT_BYREFI};

__result = CA_MethodInvokeEx (objectHandle, errorInfo, &BQ_IID_EV2300_,
0x7, CAVT_EMPTY, NULL, 3, __paramTypes,
nNumBrdsToGet, nNumBrds, listBrdNames);

return __result;
}

 

Could the ActiveX Control Wizard be incorrect and the expected parameter types are wrong?

 

 

0 Kudos
Message 3 of 12
(5,795 Views)
Solution
Accepted by topic author TestEngineer503

Something is definitely amiss, because the last two parameters are both output parameters yet they are being defined as input parameters. So either the ActiveX control has bad IDL in it or the ActiveX controller wizard has made a mistake.

 

You might try a little experiment by changing the two CAVT_BYREFI references in the __paramTypes array to CAVT_BYREFO to see if that makes a difference. Rationale: for strings, CA_MethodInvokeEx probably has to convert from C string type to BSTR for input parameters, and from BSTR back to C string for output parameters. If it doesn't think a parameter is an output parameter, my guess is it probably won't bother converting back. For longs (which are a native ActiveX type) it doesn't have to do any conversion.

--
Martin
Certified CVI Developer
Message 4 of 12
(5,786 Views)
Thanks a lot!  Changing CAVT_BYREFI to CAVT_BYREFO made everything happy.  That seemed odd to me too but I just wasn't sure enough about my understanding of it to make the change.  Now a number of other wrappers have a similar problem so I'll go fix those.
0 Kudos
Message 5 of 12
(5,780 Views)
Good. Don't forget to free the string memory when you have finished with it. CA_FreeMemory() is (probably) your man.
Message Edited by msaxon on 26-10-2009 05:09 PM
--
Martin
Certified CVI Developer
0 Kudos
Message 6 of 12
(5,774 Views)

I need to raise this thread from the land of a year ago because I'm having the exact same problem.  The twist is that I don't have access to the raw wrapper code.

 

I got the .dll and .oxc files direct from Texas Instruments.  I imported it as an activex control using the advance tools menu, and the functions show up, but I can't get them to work. 

 

So, I require the answer for one of two questions:

 

1) How do I get access to the wrapper code?

2) How do I get the activeX control to work without editing the wrapper directly?

--

Ro ma wa ichi ni chi ni shi te na ra zu
0 Kudos
Message 7 of 12
(5,049 Views)

Would it be possible to convert the Cstring to a BSTR and vice versa?  Since I can't apparently edit the dll wrapper (since I don't have the source code) that sounds like it would solve the problem.

 

Thanks.

--

Ro ma wa ichi ni chi ni shi te na ra zu
0 Kudos
Message 8 of 12
(5,036 Views)

Whichever folder you created your instrument (.fp) in should also have .c and .h files of the same name.  The wrappers are in the .c file.

0 Kudos
Message 9 of 12
(5,021 Views)

I didn't create an instrument folder.

 

I imported the dll into an activeX control to the Palette using the Tools menu.  The DLL was in my win32 folder, and there was no header file associated with it because it was generated for VB6 (It works with VB6 code, incidentally).  Then I added an ActiveX VI from the Connectivity Palette, followed by tying it to the ActiveX control associated with the DLL, and selecting the method I want to invoke.  This has the downside that there isn't a help file for any of the invoke methods, but since I'm familiar with how they work in VB6 I should be able to figure most of it out. 

 

The problem I'm having is that GetFreeBoards doesn't return anything useful, and I can't use the output of the string output with the OpenDevice function that requires a device name.

 

I'm very new to Labview (I'm using 8.5, if that helps.  My plan is to upgrade to the latest version soon.) so if a folder was created that has the .h and .c files in it, I don't know where that would be.

--

Ro ma wa ichi ni chi ni shi te na ra zu
0 Kudos
Message 10 of 12
(4,994 Views)