03-14-2013 02:49 PM - edited 03-14-2013 02:52 PM
Recently I have been exploring how to best expose actor-oriented LV code to .Net developers. I created a simple Metronome actor (not AF) in Labview and built an interop assembly. I also have created a simple c# client app to call the assembly. However, I'm getting an exception when I call the assembly method that invokes LV code initializing the actor.
The exception message is:
Failed to convert the LV Class to the .NET class because LV cannot get the LV Class Instance.
For reference, here's the C# code that generates the error. (Attached zip file contains entire LV and VS projects as well as the built assembly.)
// Create the message queues MessageQueue metQ; // Queue to send messages to the metronome MessageQueue myQ; // Queue to receive messages from the metronome MessageQueue.Init(out myQ); // Create the metronome and launch it under a Labview logical thread Metronome met; Metronome.Init(myQ, out met, out metQ); // Raises Exception
And here's the equivalent LV code using the same vis the .Net assembly delegates to, which works just fine.
The MessageQueue.Init method isn't doing anything particularly complicated. It accepts and stores myQ so the Metronome can send messages out, creates, stores, and returns metQ so it can receive messages, and returns a newly created Metronome object. That's it. There are several layers of abstraction between the exposed MessageQueue object and the native LV queue, but I don't think that's related to the error I'm seeing.
Does anyone know what might be causing this error?
[Closely related cross-post on LAVA.]
03-19-2013 08:24 PM
Bump. Still hoping for someone who knows more than I to respond.
04-08-2013 01:31 PM - edited 04-08-2013 01:32 PM
Hi Daklu,
First of all can you elaborate a little more on what the Visual Studio code, is that the Metronome or is the Metronome in LabVIEW. So you are calling the Metronome through LabVIEW correct? Is there an error code/number that you get with your error?
Regards,
Basil
04-08-2013 03:35 PM
Thanks for taking a look at this Basil. Actually, you have it backwards. I've attached another zip. Functionally I think it's identical to the earlier one, but I've added more icons to the vis and comments to SimpleTest.vi. Hopefully it will help.
The Metronome is implemented in Labview. LapDog.Metronome.lvlib contains the Metronome class and the message classes for interacting with a running metronome. The core metronome functionality is implemented in ExecutionLoop.vi. SimpleTest.vi is an example of how the Metronome is used in Labview. This verifies the metronome is working as expected.
The Interop Layer folder contains simple wrappers around the classes in the LapDog.Metronome library. The MetronomeInterop build spec only references the vis in the Interop Layer folder. InteropLayerTest.vi does the exact same thing as SimpleTest.vi, except it uses the Interop Layer vis instead of the LapDog.Metronome library. This vi verifies the interop layer vis work as expected.
Ultimately what I'm trying to do with this prototype is write c# code that uses the metronome in the same way SimpleTest and InteropLayerTest do. The c# code isn't complete yet, but I've run into this error and it is blocking further progress. The exception is occurring when I run the c# code. The only information visual studio is giving me is,
Exception Type: NationalInstruments.LabVIEW.Interop.VIAssemblyException
Exception Message: Failed to convert the LV Class to the .NET class because LV cannot get the LV Class Instance.
If I recall correctly the exception only occurs on methods that have both input and output parameters. So,
MessageQueue.Init(out myQ); and
Metronome.LaunchConcurrent(met);
do not raise an exception, but
Metronome.Init(myQ, out met, out metQ);
does.
I don't know if there's something wrong with my interop build spec, if there's an error somewhere inside Labview, or if I'm just trying to do something that isn't possible.
(If the LapDog.Messaging library is confusing you, it's easiest to think about it as an OO implementation of string/variant messages.)
04-08-2013 04:41 PM
I should also explain what the metronome is intended to do...
The purpose of the metronome is to send a specific message at regular intervals. It runs as a parallel logical thread, and sending a message at regular intervals is all it does. I use them to send messages to message handling loops when some action needs to be done regularly and I don't want to rely on the Dequeue timeout.
04-25-2013 06:14 AM
Basil,
Have you found any information about what is causing the error?
04-26-2013 02:12 PM
Hi Daklu,
I'm working on playing around with your code to see if I can get anything figured out. I'll post back when I make any headway.
05-07-2013 12:07 PM
James,
Have you made any progress on this? Do you understand what I'm trying to do, or do I need to explain it further?
12-12-2013 01:38 PM
12-12-2013 04:08 PM
Unfortunately no. I was unable to get any traction with NI on this issue.