LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

ActiveX controller methods import as callbacks

I tried calling this ActiveX server in a few other environments. In TestStand the only object that is available is the IMach4. In LabVIEW if i try to call the same object I get an error.

 

2009-12-22_105217.jpg

 

But I can call the  IMyScriptObject with no errors. Does this company have examples of how to call their code, can you provide one?

Richard S -- National Instruments -- (former) Applications Engineer -- Data Acquisition with TestStand
0 Kudos
Message 11 of 21
(3,866 Views)

Richard,

 

They provided a sample project using MFC.   I uploaded the file to the FTP site using the same file name (143367.rar).

 

The Code function we talked about previously, which should be a method but is shows up as an event, is called in the Code method defined in CMyScriptObjcet.h like this:

 

     void Code(LPCTSTR Command)
    {
        static BYTE parms[] = VTS_BSTR ;
        InvokeHelper(0x1c, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Command);
    }

 

Tony

0 Kudos
Message 12 of 21
(3,817 Views)

Tony,

 

I looked into the library that was provided as part of this active x server, and the functions are declared in in the typedef as events. So CVI is recognizing the functions in accordance with how the Active X server was built and defined. That being said we can call callbacks directly as if they were functions (because they are) though they would not leveredge the eventdata that is traditionally passed into callbacks. 

 

Since installing the origional mach4 software, i have had to reformat my machine. Can you please post the generated .fp from CVI as well as the supporting files (should be the same name, but have different extensions such as .h, .c, etc.) ? 

Richard S -- National Instruments -- (former) Applications Engineer -- Data Acquisition with TestStand
0 Kudos
Message 13 of 21
(3,791 Views)

I uploaded a ZIP file with all the Mach4 created files in it.  Since the original 143367.zip file was still there, I named this one 143367b.zip.

 

Tony

0 Kudos
Message 14 of 21
(3,766 Views)

Richard,

 

I decided to try your suggestion of just calling the callback directly.  However, I ran into problems trying to register the callback.  Here's my test code:

 

void Test(void);

static CAObjHandle Mach4Server;

HRESULT CVICALLBACK CodeCallback (CAObjHandle caServerObjHandle,
                                  void *caCallbackData,
                                  char *command);


void Test(void)
{
    char ResultDescr[1000];
   
    HRESULT Result = Mach4_ActiveIMach4 (NULL, 1, LOCALE_NEUTRAL, 0, &Mach4Server);
    CA_GetAutomationErrorString (Result, ResultDescr, sizeof(ResultDescr));
    InsertTextBoxLine (panelHandle, PANEL_txt, -1, ResultDescr);
   
    Result = Mach4_IMyScriptObjectRegOnCode (Mach4Server, CodeCallback, NULL, 1, NULL);
    CA_GetAutomationErrorString (Result, ResultDescr, sizeof(ResultDescr));
    InsertTextBoxLine (panelHandle, PANEL_txt, -1, ResultDescr);
} /* Test */


HRESULT CVICALLBACK CodeCallback (CAObjHandle caServerObjHandle,
                                  void *caCallbackData,
                                  char *command)
{
    return S_OK;
} /* CodeCallback */
 

 

The call to Mach4_IMyScriptObjectRegOnCode returns error 0x80004002 = "No sych interface supported".

 

Tony

 

P.S. I wasn't sure whether I should start with Mach4_ActiveIMach4 or Mach4_NewIMach4.  Through trial and error I found that I first needed to open the Mach program and then call Mach4_ActiveIMach4.  Any other combination locked up CVI or put me in an infinite loop of popup error messages from Mach.

0 Kudos
Message 15 of 21
(3,748 Views)

Tony,

 

I'm still looking into this but don't have any additional information at this time.

Richard S -- National Instruments -- (former) Applications Engineer -- Data Acquisition with TestStand
0 Kudos
Message 16 of 21
(3,716 Views)

Tony,

 

When looking at the type library for the ActiveX interface in question, we see that the methods that are being imported as callback registration routines are marked with the [default, source] attribute.

 

 

According to msdn, http://msdn.microsoft.com/en-us/library/aa232463%28VS.60%29.aspx this means that these methods are called, rather than implemented.  Basically - these are events that can occur, and the user must register for. We will need to get Mach involved to verify that the IDL matches what their developers expect the IDL to look like. From all indications, it seems we are importing the members correctly. 

 

The members highlighted in the picture follow a design pattern http://en.wikipedia.org/wiki/Component_Object_Model#COM_as_an_object_framework   that would denote the members are events.

 

Capture-25.PNG

Richard S -- National Instruments -- (former) Applications Engineer -- Data Acquisition with TestStand
0 Kudos
Message 17 of 21
(3,688 Views)

Thanks for the explanation.  I'm going to email this thread to Mach's tech support and see what they say.

 

Tony

0 Kudos
Message 18 of 21
(3,686 Views)

I've spent the last couple of weeks trying to go a different direction.  I've run into another brick wall going down that path, but I learned some things that may help with the original question of how to use this ActiveX server in CVI.

 

To keep things short I won't bother explaining what I did or why, just what I found out.  I can use this ActiveX server in .NET VB with the following code:

 

        Dim Mach As Mach4.IMach4
        Dim ScriptObject As Mach4.IMyScriptObject

 

        Mach = GetObject(, "Mach4.Document")
        ScriptObject = Mach.GetScriptDispatch()
        ScriptObject.Code(GCodeCommand)

 

The last line with the call to the Code function is what I'm trying to get to in CVI.  So here's what I noticed: The Code function isn't accessed directly from the IMach4 object in VB.  I first have to call GetScriptDisptach.  Then I use the handle rerturned by that function to call Code.  

 

The created FP in CVI has a GetScriptDispatch command, too.  I can call it like this:

 

    CAObjHandle MachHandle;
    CAObjHandle ScriptObjectHandle;

 

    Mach4_OpenIMach4 ("c:\\Mach3\\Mach3.exe", NULL, 1, LOCALE_NEUTRAL, 0, &MachHandle);
    Mach4_IMach4GetScriptDispatch (MachHandle, NULL, &ScriptObjectHandle);

 

My next step would be to use the ScriptObjectHandle to call the Code function.  But of course the '.' syntax doesn't work here (as in "ScriptObjectHandle.Code...").  I tried to find some general information in the help file on what I can do with a CAObjectHandle once I've got it, but I couldn't find any general overview that pointed me in the right direction.  I'm assuming there's some function call or mapping process that will let me access the members of the ScriptObjectHandle interface, I just can't figure out what they are.

 

Anyone have any ideas?

0 Kudos
Message 19 of 21
(3,603 Views)

Hey Tony - 

 

I've been working with Richard on this, and may have something you can work with.  

 

We still hold that if these methods are meant to be callable, the type library has been created incorrectly, and should ultimately be corrected.  

 

However, I have been able to step into our code that automatically generates the fp, and modify the generation routine to create methods that should be callable for this particular activex interface.  I have attached the necessary files below for you.  One thing to note is that the IMyScriptObject now has three methods New/Open/ActiveIMyScriptObject that most likely never need to be used.  To get the object handle to pass to these methods (such as Mach4_IMyScriptObjectCode), you should continue to use the method you mentioned earlier - Mach4_IMach4GetScriptDispatch.  

 

I am not able to test this, so I'm not entirely sure it will work for you.  Take a look at it and let me know if it will work for you. 

 

NickB

National Instruments 

Message 20 of 21
(3,570 Views)