LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

.NET DLL Event Handling . What am I doing wrong

Hello everyone, 

 

I am writing a program to USB interface with a splicing machine.

The connection is working properly and I am able to send receive/commands to the machine.

My problem is the event handling. I tried different things to fix this issue and tried different examples including the NI default ones. These examples worked on my machine so I don't think that the problem is specific to my software config.

Basically, I am loading the DLL in Labview, callign the constructor then using Reg Event Callback to register the events:

Capture1.PNG

 

I select the event ( Attached in this case)  right click on the VI ref and create the call back

Capture3.png.

I put in a one button messageBox for debugging..

Capture2.PNG

The Attached event is supposed to fire when the USB machien is connected. 

I never got the Callback VI to execute and I don;t know how to troubleshoot. I tried a debugger that I found online ( debugView) to see if something happens in the background when I connect disconnect the machine and I actually see this everytiem I plug/unplug the USB device:

[8600] FMAPP: Debug function is disable
[8600] FMAPP is running
[8916] FMAPP: Debug function is disable
[8916] FMAPP is running

 

I hope someone call show me how to troubleshoot this issue further cause I am running out of ideas... A C# event handler works just fine and I am able to capture these events.

Some people reported a NULL parameter issue and it looks like an unsolved issue based on the documentation I found so far. I am not sure I have this problem but I can't think of a way to confirm this. Some people are saying that they had to come up with a wrapper DLL to go around that issue with Null parameter in event calls. I wish someone will help me to start somewhere regardign this as well.

 

Thanks in advance for helping !

 

 

 

 

 

 

0 Kudos
Message 1 of 8
(7,471 Views)

Hello M_AmineJ, I looked into it a little bit. Can you tell me the LabVIEW version you are using? Also, have you seen this information? http://digital.ni.com/public.nsf/allkb/2AF19EBDFA4AC82D862576B6006E7FE8?OpenDocument  if not, look into it and it might guide you a little in solving this issue.

 

Regards

Juan B

National Instruments

0 Kudos
Message 2 of 8
(7,426 Views)

Hello Juan, 

 

I am using Labview 14.0f1 32-bit on windows 7 64-bit. .Net framework 4.5.1/ v4.0/ 3.5 / 3.0 and 2.0

 

I looked at that document before and found that this is not the issue I am having. Nothing pops up when the event occurs.

 

Thanks 

Amine

0 Kudos
Message 3 of 8
(7,409 Views)

Hi!

I was going through the forum threads you posted and it seems to me that the only way to know if you are having the same issue is to try and implement the things they said solved their problem. As I see it, it is quite possible is the same, considering the description you gave and the description you are giving. Have you tried implementing the solutions posted on those forums? If so, did you notice any changes? what was the observed behavior after implementing those changes?  

Regards

Juan B.

National Instruments

0 Kudos
Message 4 of 8
(7,395 Views)

Alright, I ve got sometime this week to go and investigate this issue further. I tried to do what other people did to solve this issue : a wrapper DLL

Basically, instead of handling the event fired by my device DLL directly in Labview, I created an intermediate DLL that will capture that event and fires a second event that does not pass NULL in argument and therefore LabVIEW can handle.

I am testing my wrapper DLL with C# then Labview. I got everything to work on C# but not with LabVIEW for a reason I still don't know.

 

The Device DLL fires two events: “attached” and “detached”, when the device is connected/disconnected to a USB port.

This event will is captured in the wrapper DLL and triggers usb_attached method:

Usb.Attached += new EventHandler(usb_attached);

 

Here is the usb attached method declaratuion:

public void usb_attached(object sender, System.EventArgs e)

 Again, this event cannot be handled in Labview diretly because the System.EventArgs object is passing a NULL variable.

The work around is to call another event that will have something other than Null in parameters.

So I am creating
USBstatusClass that will have that event. I am also creating my own USBconnectionArgs class that evherits from System.EventArgs and that will contain event data.

 

In the constructor of the USBstatusClass, I am attaching the device DLL events and forwarding the call to my newly created event.

 

Here is the code for the entire wrapper DLL.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WrapperDLL
{

    public class USBconnectionArgs : EventArgs
    {
        private string USBstatus;
        public string status
        {
            set
            {
                USBstatus = value;
            }
            get
            {
                return this.USBstatus;
            }
        }
    }

    public class USBstatusClass
    {

        public event USBconnectionHandler USBevent;
        public delegate void USBconnectionHandler(USBstatusClass m, USBconnectionArgs e);

        USBconnectionArgs usbStatus = new USBconnectionArgs();


        public USBstatusClass(UsbFsm100ServerClass Usb)
        {

            Usb.Attached += new EventHandler(usb_attached);                 
            Usb.Detached += new EventHandler(usb_detached);                 
            MessageBox.Show("Hello 1");
        }
        
        public void usb_attached(object sender, System.EventArgs e)
        {
            USBconnected();
            MessageBox.Show("Hello 2");
        }

        public void usb_detached(object sender, System.EventArgs e)
        {
            USBdisconnected();
        }

        public void USBconnected()
        {
            if (USBevent != null)
            {
                usbStatus.status = "YES";
                USBevent(this, usbStatus);
            }
        }


        public void USBdisconnected()
        {
            if (USBevent != null)
            {
                usbStatus.status = "NO";
                USBevent(this, usbStatus);
            }
        }
    }
}

 

 

In C# this DLL works perfectly. You can find the code in the attachment for the receiver application that will capture the event created by USBstatusClass. Note that I am inserting few messageboxes in the code for debugging.

My issue is really with Labview. The constructor loads the function perfectly. But when the device is connected, there is not event captured.

When I call the USBconnected() function from Labview, the event got actually fired and captured in Labview. However, the same event is not triggered when the USB is connected. Again, this wrapper DLL works perfectly in C#..

 

 Here is my Labview Code:

Capture.PNG

 

First I use user32.dll ( FindWindowA() ) method to get a IntPtr anbd initialize the Device DLL ( call the constructor), then I init the driver using the InitDriver invoke node.

I then Call the constructor of my status class and register the event into. I am putting a messageBox in the CallBAck VI to troubleshoot.

The same concept is written in C# ( see code below:

namespace WrapperForm
{
    
    public partial class Form1 : Form
    {
        USBstatusClass m;
        private UsbFsm100ServerClass Usb;
       
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load_1(object sender, EventArgs e)
        {
            Usb = new UsbFsm100ServerClass(this.Handle);

            USBstatusClass m = new USBstatusClass(Usb);

            m.USBevent += new USBstatusClass.USBconnectionHandler(HeardIt); // New event
            
        }

        private void HeardIt(USBstatusClass m, USBconnectionArgs e)
        {
            label1.Text = e.status;

            if (e.status == "YES")
            {
                label1.ForeColor = Color.Blue;
            }
            else label1.ForeColor = Color.Silver;

        }
          
    } 
}

 

So when I manually trigger the event created by USBstatusClass, I see the messageBox appearing. But when I physically connect the machine to USB, C# detects it and fires the event, but this does not happen in LAbview.

 

PLEASE HELP. I KIND OF RUN OUT OF IDEAS Smiley Frustrated

0 Kudos
Message 5 of 8
(7,225 Views)

Attaching C3 files and Labview code..

Download All
0 Kudos
Message 6 of 8
(7,217 Views)

Hey, this is a little bit hard to follow because you seem to be doing a few things:

1. You call an actual dll using a call library function node. For clarity, I'm going to call this the "CLFN" rather than "DLL".

2. You call a .net assembly (which may be a dll, but not a real dll). I'm going to call this the "assembly" rather than "DLL".

3. You also appear to be sharing a pointer between the unmanaged CLFN call and the managed (ie in the .net runtime) assembly call.

4. You are converting *not casting* a U32 into an I32 and telling .net its a pointer.

 

With #3/4, I'm surprised the code works at all. Are you absolutly certain you can pass the pointer between the CLFN and the assembly? At the very least you should probably type cast rather than convert betwen U32 and I32. Besides that...

What is the pointer? Who owns the pointer? Why is it being shared between a CLFN and .net? What is the CLFN call?

0 Kudos
Message 7 of 8
(7,199 Views)

Hello M_AmineJ,

I've taken a look into your VI and the codes. I found a working solution (event is fired and I got a message box saying "YES").

Unfortunately I have no clue about how to fire the event with an USB device, so I have only tested it with your USBConnected method in the wrapper.dll. Do I need some special hardware?

I've attached an archive where I altered your VI and made a project including the DLLs and a Callback-VI. I had to copy the DLLs next to the LabVIEW.exe in order to execute the VI, else LabVIEW responds with something like: "could not find wdapi1110.dll...". Anyways, the attached files work for me.

However, I think you should do a couple of things to prevent more complications:


- First of all, LabVIEW should only interact with the wrapper. So you have to implement wrapper functions not only for events, but also for any method or property you want use (including any type of data you want to support). It is some work, but with that you have total control between the UsbFsm100ServerClass and LabVIEW.

- Try to do as much as possible in the wrapper. This allows you to test it properly and you'll have less to worry in LabVIEW. Notice that any time you replace the DLL you'll have to restart LabVIEW and might even have to reassign the calls because of changed names or types (not only Callbacks, but also properties, methods, etc... -.-). This is again a reason to implement the wrapper first and test it properly.

- The call to the user32.dll in your example is really awkward and like dems I'm uncertain if that is even legit. You might point to an arbitrary address at that point which might or might not cause problems in the future. The UsbFsm100ServerClass provides a constructor without the _handle parameter which you should use. So when you call to the UsbFsm100ServerClass, use the constructor without parameters and the InitDriver method like this: InitDriver(IntPtr.Zero);
I've done the same thing in the attached project, but still, better move it into the wrapper.

Also notice, that whenever you change one of the objects in your event (sender or e), you'll have to create a new Callback-VI.

Don't forget to give Kudos to:

http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Support-NULL-parameter-in-NET-Event-Callback/idc-p/304...

or you will have to learn C# to solve such problems forever! 🙂

0 Kudos
Message 8 of 8
(7,175 Views)