LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Return Value by System_Data_SqlClient_SqlDataReader_GetValues returns NULL(s)

Hi RC,

I understand that you don't want to spend time on the C++ program, but I wanted to be certain that this method (GetValues) was working properly in a non-CVI related environment. Having that fact puts the emphasis on CVI in that perhaps we are doing something strange.

With that said, I appreciate you sending the CVI code to the support team. If you could also submit an SQL statement of some sort that would popule a database with random data, then we could test out the CVI code. After we can reproduce the issue, then we will probably take a step backward and perform the same thing in .NET to valide that the method call works like we think it works which is my concern.

In either way, we can look into this for you to see what is expected. Please submit the SQL statements to the support team so we can keep track of the issue.

Thanks & Best Regards,
Jonathan N.
National Instruments
0 Kudos
Message 11 of 14
(1,473 Views)
You can basically connect to any MS SQL Server database and test the routine. If you can get it to work on your system send me the code and I can try it here. The code I sent to support is easily modifyable to connect to a different data base and execute a different Select command for retrieving the data.
0 Kudos
Message 12 of 14
(1,463 Views)

Hi Rene,

After running through some tests in .NET and CVI, I have figured out what is going on.  So first off, you were right about how the
GetValues method was supposed to work as I validated that by creating a C# program that communicated to a database and used that GetValues method.

The
GetValues method is actually quite odd in the sense that it takes an input array and fills it up. This seems to violate one of Microsoft's own recommendations against API methods filling up input array parameters.

The significance of that fact is that CVI only marshals arrays back if the parameter of a function is marked as an output parameter or reference parameter (i.e. keywords out, ref, ByRef, etc; For example, check out the
System.Array.Resize method).  Since this GetValues "values" array parameter was not marked in this way, the output values returned by the GetValues method inside our wrapper were not sent back to the caller (your program).  Basically the reason that the array contained NULL values is that the wrapper didn't convert the .NET array values back to a C array because we think the GetValues array parameter is input only. 

So my initial fix was to call the
CDotNetGetArrayElements method in the wrapper after the Invoke call and pass it the array handle (values__) to copy the elements to the values parameter that was sent in. However, I soon realized there was a problem with that because that function allocates the buffer to hold the elements. So instead, you need to use CDotNetGettArrayElement in a loop and fill up the values array.  For example, you would say:

/* values__ is the array that was returned by the Invoke call.  values is our array we sent into the wrapper function

for (i = 0; i < __valuesLength; ++i)    // valuesLength was an input parameter
       
__errChk(CDotNetGetArrayElement(values__, CDOTNET_OBJECT, 1, &i, &values[i]));  

I have attached what my GetValues function looks like after inserting that statement and of course declaring the variable i. I tested this out on my side with the database I created and it worked.

Hope this helps and let me know if you have any trouble.

Best Regards,

Jonathan N.
National Instruments
Message 13 of 14
(1,440 Views)
Hi Jonathan
 
That seems to do the trick. Thanks for all your efforts.
 
Best Regards,
Rene
0 Kudos
Message 14 of 14
(1,406 Views)