Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Detecting changes using PCI-6527 with NI-DAQmx

reader->SynchronizingObject = this;
// error C2664: 'NationalInstruments::DAQmx::DigitalSingleChannelReader::set_SynchronizingObject' : cannot convert parameter 1 from 'CDiomxHandler *const ' to 'System::ComponentModel::ISynchronizeInvoke __gc *'


The synchronizing object must be an object that implements the ISynchronizeInvoke interface. When the synchronizing object is set, that object serializes (or otherwise synchronizes) methods, events, and callbacks that use the synchronizing object, for instance if you set the synchronizing object to a Windows Form object, all calls occur in the UI thread of that Form. Things that implement ISynchronizeInvoke include Windows Forms forms and controls.

If you are not
using Windows Forms for your UI, just leave this unset. The callbacks will then occur in a separate thread and, in your callback, you must do any synchronization that is necessary.

reader->BeginReadSingleSampleMultiLine (System::AsyncCallback (OnDataReady), NULL);
// error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'System::AsyncCallback'


The syntax for creating an instance of a delegate is a little different in C++. Assuming that OnDataReady is a method of the CDiomxHandler class and that "this" is a pointer to a CDiomxHandler instance (i.e. you are making the call from within a member function), you would use new System::AsyncCallback(this,&CDiomxHandler::OnDataReady) to get a pointer to a delegate.

You can find more information about the syntax for the Managed Extensions to C++ in the Visual Studio online help (or on Microsoft's MSDN website).

Tony H.
0 Kudos
Message 21 of 27
(1,968 Views)
I tried this:
'reader->BeginReadSingleSampleMultiLine (new System::AsyncCallback (this, &CDiomxHandler::OnDataReady), NULL);'
and when I compile I get an error stating:
'error C3363: 'void CDiomxHandler::OnDataReady(System::IAsyncResult __gc *)' : cannot create a delegate handler for 'System::AsyncCallback' from a non-member function or a member of an unmanaged class
'
0 Kudos
Message 22 of 27
(1,968 Views)
Your callback must be in a managed class (one marked with __gc). If CDiomxHandler cannot be made into a managed class, you can use a managed class to call into CDiomxHandler like this (similar to the suggestion in the documentation for Compiler Error C3363😞

__gc class ThunkClass
{
static void Thunk(IAsyncResult* ar)
{
myCDiomxHandlerInstance.OnDataReady(ar);
}
}

//...

reader->BeginReadSingleSampleMultiLine (new System::AsyncCallback (0, &ThunkClass::Thunk), NULL);

Tony H.
Measurement Studio
0 Kudos
Message 23 of 27
(1,968 Views)
Thanks for your reply. Will try this.
0 Kudos
Message 24 of 27
(1,968 Views)
Tried your tip. It workes OK, but only once. After it reads one input, then it stops reading.

Classes CDiomxHandler and ThunkClass look like this:
'class CDiomxHandler
{
public:
gcroot reader;
public:
CDiomxHandler(void);
~CDiomxHandler(void);
void WriteToDIO (void);
void ClearDioOutput (void);
void ReadDioInput (void);
void OnDataReady(System::IAsyncResult *result);
};

__gc class ThunkClass
{
public:
static void Thunk(System::IAsyncResult* ar)
{
CDiomxHandler* pThis = (CDiomxHandler*)AfxGetMainWnd ();
pThis->OnDataReady (ar);
}
};'

The function that controls readings looks like this:
'void CDiomxHandler:
:ReadDioInput (void)
{
Task *DIORTask = new Task ("DigitalReadTask");

DIORTask->DIChannels->CreateChannel ("Dev1/Port0/Line0:7", "In1", ChannelLineGrouping::OneChannelForAllLines);
Timing *timing = DIORTask->Timing;
timing->ConfigureChangeDetection ("Dev1/Port0/Line0:7", "Dev1/Port0/Line0:7", SampleQuantityMode::ContinuousSamples);

reader = new DigitalSingleChannelReader (DIORTask->Stream);
reader->BeginReadSingleSampleMultiLine (new System::AsyncCallback (NULL, &ThunkClass::Thunk), NULL);
}'

And callback function looks like this:
'void CDiomxHandler::OnDataReady (System::IAsyncResult *result)
{
AfxMessageBox ("YES YES!");
reader->EndReadSingleSampleMultiLine (result);
reader->BeginReadSingleSampleMultiLine (new System::AsyncCallback (NULL, &ThunkClass::Thunk), NULL);
}'

Any suggestions to what am I doing wrong?
0 Kudos
Message 25 of 27
(1,968 Views)
As I see no answer in more than a week, I suppose, that you missed my last post.
Anyhow the problem is described above. Does anybody know how to fix the problem?
0 Kudos
Message 26 of 27
(1,968 Views)


kovalenkov a écrit:
Hi!

I am thiniking of changing from Tradintional DAQ to DAQmx with Visual C++ .NET 2003. I downloaded NI-DAQ 7.1, where PCI-6527 is supported by DAQmx.
The problem I encountered is lack of documentation for using DAQmx functions and properties.
I have several questions:
1. Where can I get detailed documentation for DAQmx (I already have both help files)?
2. How to detect a change on input? In Traditional DAQ there was a function called DIG_Change_Message_Config (...), where you could set up all the details about detecting changes.
3. Where to get more examples for VC++ .NEt 2003 and DAQmx?

Thank you for your reply.



Hi,
I think your solution is in the Ni-DAQmx 7.4. You have the event properties, equivalent to the 'DIG_Change_Message_Config' function in traditional NI-DAQ.
Regards.
Laurent
0 Kudos
Message 27 of 27
(1,848 Views)