LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Calling LabVIEW DLL from C with 2d array strings

I am trying to write a DLL in C that calls a LabVIEW DLL that has a number of functions that each return a 2D array of strings which are the formatted measurements, with column 1 being the measurement name and column 2 being the measurement. I wanted to use the 2D array of strings since this would give a uniform interface for returning measurements. Ive cobbled together bits and pieces of messages and example code I've found here into something that almost works, and was hoping someone with a little more experience in interfacing C with LabVIEW DLLs would be able to help me.

Here's a little snippet from the header file generated when building the LabVIEW DLL:

typedef struct {
    long dimSizes[2];
    LStrHandle String[1];
} TD1;

typedef TD1 **TD1Hdl;

long __cdecl TestVI(char serialNumber[],  TD1Hdl *formattedMeasurements, char ErrorDescription[], long len);
The "TestVI" VI generates a 2D array of strings. The cell contents and number of rows are random to simulate different measurement names and measurements.

Here's a snippet for the wrapper class:
class CArgoTestsLabVIEW  
{
   public:
      CArgoTestsLabVIEW();
      virtual ~CArgoTestsLabVIEW();

      // test modules called from parent DLL
      BOOL GetResult_LV(CString resultName, double *result);
      long TestVI_LV(CString serialNumber);
   
   private:
      TD1Hdl m_LVStringArray;
      CMapStringToString   m_resultMap;
      
      InitMeasurementsArray();
      PopulateResultMap();
}

The "m_LVStringArray" is intended to hold the 2D array of strings that the test modules spit out. The "m_resultMap" is just for accessing the measurements from the parent DLL via the "GetResult_LV" function.

The implementation of TestVI_LV is:
long CArgoTestsLabVIEW::TestVI_LV(CString serialNumber)
{
    long rc = 0;
    char errStr[BUFFERLEN];

    strcpy(errStr,"");

    rc = InitMeasurementsArray();

    if (rc == 0) {
        rc = TestVI(serialNumber.GetBuffer(serialNumber.GetLength()), &m_LVStringArray, errStr, BUFFERLEN);
        PopulateResultMap();
    }
    return rc;
}
The accessor functions InitMeasurementsArray and PopulateResultMap are:
long CArgoTestsLabVIEW::InitMeasurementsArray()
{
	MgErr err;

	if (m_LVStringArray)
	{
		DSDisposeHandle(m_LVStringArray);
	}
	m_LVStringArray = (TD1Hdl)DSNewHandle(sizeof(TD1));
        // code to check for NULL

	// Set number of strings in array to 0
	(*m_LVStringArray)->dimSizes[0] = 0;
	(*m_LVStringArray)->dimSizes[1] = 0;
		
	// Set total size of array structure. For now it is only as big as the long variable.
	err = DSSetHandleSize((UHandle)m_LVStringArray, sizeof(long));
	// code to check for error 

	return 0;
}

void CArgoTestsLabVIEW::PopulateResultMap()
{
	int	numberOfResults;
	int i;
	int charCnt;

	numberOfResults = (*m_LVStringArray)->dimSizes[0];

	if (numberOfResults == 0) {
		return;
	}

	m_resultMap.RemoveAll();

	for (i = 0; i < numberOfResults; i++) {
		charCnt = (*((*m_LVStringArray)->String[i * 2]))->cnt;
		(*((*m_LVStringArray)->String[i * 2]))->str[charCnt] = '\0';
		charCnt = (*((*m_LVStringArray)->String[i * 2 + 1]))->cnt;
		(*((*m_LVStringArray)->String[i * 2 + 1]))->str[charCnt] = '\0';

		m_resultMap.SetAt((LPCTSTR)  (*((*m_LVStringArray)->String[i * 2]))->str, (LPCTSTR)  (*((*m_LVStringArray)->String[i * 2 + 1]))->str);
	}
}
The problem I have is that I eventually get an access violation from the run-time engine if I try to call the test VI in a loop. I'm obviously having a memory management problem, but it escapes me as to where the problem is. Anybody have any ideas?
0 Kudos
Message 1 of 2
(2,976 Views)


smercurio_fc wrote:

The problem I have is that I eventually get an access violation from the run-time engine if I try to call the test VI in a loop. I'm obviously having a memory management problem, but it escapes me as to where the problem is. Anybody have any ideas?

...
(*((*m_LVStringArray)->String[i * 2]))->str[charCnt] = '\0';

Hi smercurio,
      Have you solved this?  I don't work with C much anymore, but it looks, here, as if the memory at str[charCnt] isn't yours to address/change.
Is index "charCnt" one char past the end of the String-memory allocated by LabVIEW? 

 
just an idea! Smiley Happy
 
Hmmm, maybe page 9 is a bit far back to fish in the unanswered posts. Smiley Tongue

Message Edited by Dynamik on 03-03-2006 02:03 AM

When they give imbeciles handicap-parking, I won't have so far to walk!
0 Kudos
Message 2 of 2
(2,899 Views)