From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Interop assembly generates AccessViolationException

Hi,

 

I am writing a .Net application that needs to read/write to an FPGA via DMA.  To do this I've written some LabVIEW VIs that do the read/write, generated a .net interop assembly and successfully incorportated this into my application.  The APIs generated by the LabVIEW builder are

 

 

public static void ReadDma32(int Channel, int DataBufferSize, out uint[] Data, out int NumberOfEntriesRead, out int ReadResult);

 

where the channel parameter identifies which DMA FIFO should be accessed.  The ReadDma32 calls block until they have any data to return so it's an asynchronous process.  This all works fine until I want to read from two different DMA channels at the same time. I then get a AccessViolationException with the message "Attempted to read or write protected memory.  This is often an indication that other memory is corrupt."  I assume this is because of some marshalling issue when two different threads call the same method at the same time.  I've tried changing the execution settings (reentrant execution) on the ReadDma32 vi but this has no effect.

Does anyone have any suggestion on how to solve this issue?  My only idea so far is to remove the channel parameter from the method signature and have separate read/write dma methods for each DMA FIFO defined.  Not very elegant.

thanks,

Ralph

public static void WriteDma32(int channel, uint[] data, out int writeResult);

0 Kudos
Message 1 of 4
(3,477 Views)

I am also getting same problem, have u got solution?

Mine is still simple case.

 

I have created interop dll for labview VI's.
I am using interop dll in .NET environment.
The method signature is 
public static void ReconstructRawData(byte COMPort, double[] FlowValuesFullScaleFlow, double[] TemperaturesC, ErrorCluster errorin, byte Gastype, bool ValueFormatrealunitsFalse, out ushort GasDensity, out double[,] RawData, out ushort MaxFlow, out ushort GasID, out ErrorCluster errorout);
I am calling as shown below
byte bComPort = byte.Parse("1");
byte bGasType = byte.Parse("6");
bool blnValueFromatFalse = false;
ushort GasDensity = 0;
double[,] RawData = new double[100, 100];
//double[][] RawData = null;
ushort MaxFlow = 0;
ushort GasID = 0;
ErrorCluster ErrorIn = new ErrorCluster();
double[] dblFlowValue = new double[2];
dblFlowValue[0] = 20;
dblFlowValue[1] = 50;
double[] dblTempValue = new double[2];
dblTempValue[0] = 10;
dblTempValue[2]= 20;
But i am getting memory error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt"
Stack Trace:at System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr ptr, Int32 ofs)
at System.Runtime.InteropServices.Marshal.ReadIntPtr(IntPtr ptr)
at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalArrayOut(Type arrayType, IntPtr data)
at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalOutputArray(IntPtr entryPointDataSpace, Type arrayType, Int32 terminalIndex)
Now hot to send RawData(multidimentional array) to an method of interop dll?

I have created interop dll for labview VI's.I am using interop dll in .NET environment.The method signature is public static void ReconstructRawData(byte COMPort, double[] FlowValuesFullScaleFlow, double[] TemperaturesC, ErrorCluster errorin, byte Gastype, bool ValueFormatrealunitsFalse, out ushort GasDensity, out double[,] RawData, out ushort MaxFlow, out ushort GasID, out ErrorCluster errorout);I am calling as shown belowbyte bComPort = byte.Parse("1");byte bGasType = byte.Parse("6");bool blnValueFromatFalse = false;ushort GasDensity = 0;double[,] RawData = new double[100, 100];//double[][] RawData = null;ushort MaxFlow = 0;ushort GasID = 0;ErrorCluster ErrorIn = new ErrorCluster();double[] dblFlowValue = new double[2];dblFlowValue[0] = 20;dblFlowValue[1] = 50;double[] dblTempValue = new double[2];dblTempValue[0] = 10;dblTempValue[2]= 20;But i am getting memory error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt"Stack Trace:at System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr ptr, Int32 ofs)at System.Runtime.InteropServices.Marshal.ReadIntPtr(IntPtr ptr)at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalArrayOut(Type arrayType, IntPtr data)at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalOutputArray(IntPtr entryPointDataSpace, Type arrayType, Int32 terminalIndex)Now hot to send RawData(multidimentional array) to an method of interop dll?

 

0 Kudos
Message 2 of 4
(3,397 Views)

 

I have created interop dll for labview VI's.
I am using interop dll in .NET environment.
The method signature is 
public static void ReconstructRawData(byte COMPort, double[] FlowValuesFullScaleFlow, double[] TemperaturesC, ErrorCluster errorin, byte Gastype, bool ValueFormatrealunitsFalse, out ushort GasDensity, out double[,] RawData, out ushort MaxFlow, out ushort GasID, out ErrorCluster errorout);
I am calling as shown below
byte bComPort = byte.Parse("1");
byte bGasType = byte.Parse("6");
bool blnValueFromatFalse = false;
ushort GasDensity = 0;
double[,] RawData = new double[100, 100];
//double[][] RawData = null;
ushort MaxFlow = 0;
ushort GasID = 0;
ErrorCluster ErrorIn = new ErrorCluster();
double[] dblFlowValue = new double[2];
dblFlowValue[0] = 20;
dblFlowValue[1] = 50;
double[] dblTempValue = new double[2];
dblTempValue[0] = 10;
dblTempValue[2]= 20;
But i am getting memory error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt"
Stack Trace:at System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr ptr, Int32 ofs)
at System.Runtime.InteropServices.Marshal.ReadIntPtr(IntPtr ptr)
at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalArrayOut(Type arrayType, IntPtr data)
at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalOutputArray(IntPtr entryPointDataSpace, Type arrayType, Int32 terminalIndex)
Now hot to send RawData(multidimentional array) to an method of interop dll?

 

I have created interop dll for labview VI's.I am using interop dll in .NET environment

.The method signature is 

public static void ReconstructRawData(byte COMPort, double[] FlowValuesFullScaleFlow, double[] TemperaturesC, ErrorCluster errorin, byte Gastype, bool ValueFormatrealunitsFalse, out ushort GasDensity, out double[,] RawData, out ushort MaxFlow, out ushort GasID, out ErrorCluster errorout)

;I am calling as shown below

byte bComPort = byte.Parse("1");

byte bGasType = byte.Parse("6");

bool blnValueFromatFalse = false;

ushort GasDensity = 0;

double[,] RawData = new double[100, 100];

ushort MaxFlow = 0;

ushort GasID = 0;

ErrorCluster ErrorIn = new ErrorCluster();

double[] dblFlowValue = new double[2];dblFlowValue[0] = 20;dblFlowValue[1] = 50;

double[] dblTempValue = new double[2];dblTempValue[0] = 10;dblTempValue[2]= 20;

But i am getting memory error "Attempted to read or write protected memory.This is often an indication that other memory is corrupt"

Stack Trace:

at System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr ptr, Int32 ofs)at System.Runtime.InteropServices.Marshal.ReadIntPtr(IntPtr ptr)at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalArrayOut(Type arrayType, IntPtr data)at NationalInstruments.LabVIEW.Interop.DataMarshal.MarshalOutputArray(IntPtr entryPointDataSpace, Type arrayType, Int32 terminalIndex)

Now hoW to send RawData(multidimentional array) to an method of interop dll?

0 Kudos
Message 3 of 4
(3,395 Views)

Hi,

 

First of all I didn't use a multi-dimensional array but I'd be surprised if that made a difference.

 

I've managed to get the interop working now but there were two issues I had to overcome.

 

  1. I had to change the execution mode of the VI that I was exporting in the interop assembly.  This was because more than one thread could call the static method at any one time.  To make the change I opened the VI in LabVIEW, selected VI properties from the File menu and then changed the category to Execution.  For my needs Reentrant execution with Preallocate clone for each instance was the correct setting.
  2. The design of my LabVIEW project required VIs to be running continuously between read calls.  My static methods on the interop assembly were Open, Read and Close.  Open would start a VI running using VI server.  I had an issue where the Open call would return and a Read call issued before the VI started by Open was actually running.  I had to make sure that Open would only return when the VI was actually running.  Once this was done I knew that it was safe for the Read call to interact with the VIs.

It's worth adding some logging before and after the interop calls or using a debugger so that you can be 100% certain the number of different threads that are calling the same static method at the same time.

 

Hope this helps.


Ralph

0 Kudos
Message 4 of 4
(3,382 Views)