12-01-2009 05:23 PM
I'm trying to use a .NET DLL in a LabWindows/CVI project. The DLL comes from Microchip and is for their PICkit Serial Analyzer, a USB-to-SPI bridge device. The documentation for the DLL specifies the functions using what I assume is VB (I haven't used VB since v4). For example:
public static bool Write(byte p_slave_addr,
byte p_start_data_addr,
byte p_num_bytes_to_write,
ref byte[] p_data_array,
ref string p_script_view)
///////////////////////////////////////////////////////////////////////////
//
// Returns: True if successful, False if not
// Inputs: byte p_slave_addr - I2C slave address of UUT
// byte p_start_data_addr - I2C command code or address
// of memory to begin writing to
// byte p_num_bytes_to_write - number of bytes to be written
// byte[] p_data_array - reference to byte array that holds
// data to be written
// string p_script_view - reference to a string to which
// will be copied a formatted
// view of the command
// Description: Attempts to perform I2C write command using above
// parameters. If successful, p_num_bytes_to_write bytes are
// written to the I2C device beginning at p_start_data_addr.
// Regardless of success or failure, the PICkit status
// packet is updated after the write attempt and stored
// for retrieval by the function There_Is_A_Status_Error.
//
// NOTE: This is the first overload of this function.
//
///////////////////////////////////////////////////////////////////////////
At first I thought I just needed to create a C header function for the DLL so I could use the ActiveX Controller Wizard to create an import library. I started with a simple header file with a declaration for the first function:
bool Configure_PICkitSerial_For_I2CMaster(void);
However, when I picked the DLL in the wizard it said "Error loading type library/DLL."
I don't have Visual Studio, so I can't use it to create a wrapper DLL. Is there any other way to use this DLL in CVI?
12-02-2009 12:16 AM
Hi Tony,
CVI can create a wrapper for .NET DLLs.
Use the Tools > Create .NET Controller menu option to launch the dialog box.
See the CVI help text under Library Reference > .NET Library for further information on library usage.
Hope this helps,
12-02-2009 10:17 AM
12-02-2009 03:42 PM - edited 12-02-2009 03:43 PM
I spoke to soon. I created the function panel for the DLL and was able to call a simple function with no arguments. Now I'm trying to call a function that includes several arrays as parameters. In the provided documentation two of these arrays are typed as "ref byte[]" and one is typed as "ref string". In the function panel the first two arguments are typed as "unsigned char **" and "char **". The help contains a comment about using "CDotNetAllocateMemory" to allocate these arrays.
I don't quite understand why I need to pass a pointer to a pointer instead of just a pointer, especially if I have to allocate it myself. Nonetheless, I tried to call the function with code similar to the following:
int Status;
int SendDataLen;
int ResponseDataLen;
unsigned char *Command;
unsigned char *Response;
char *OutgoingPacket;
Command = CDotNetAllocateMemory(4);
Command[0] = 0xA0; Command[1] = 0xFB; Command[2] = 0xFB; Command[3] = 0xFB; // I'm trying to send 0xA0 0xFB 0xFB 0xFB through the SPI
Response = CDotNetAllocateMemory(4); // I expect the response to be placed in this array
OutgoingPacket = CDotNetAllocateMemory(4); // I think this is going to be a copy of the 0xA0... data, but I'm not sure
PICkitS_SPIM_Send_And_Receive_Data (4, &Command, &SendDataLen, &Response, &ResponseDataLen, 1, 1, &OutgoingPacket, &Status, NULL);
CDotNetFreeMemory (Command);
CDotNetFreeMemory (Response);
CDotNetFreeMemory (OutgoingPacket);
This generated a runtime error message about how the array (I'm not sure which one) was only 4 bytes but needed to be 4202566 bytes. Obviously I'm missing something in how these ref parameter types are supposed to be used.
12-16-2009 09:24 AM
Most probably the error is because the array length parameters you are passing are uninitialized and one of them has the large value (4202566). You need to specify the length of the arrays you pass as there is no way in C to figure out the size of arrays from just the memory addresses. I think the variables in question are SendDataLen and ResponseDataLen. Set these to 4 if you are not already doing so.
About your initial question on why you need to send pointers to these arrays instead of just the arrays: the answer is because the .NET assembly you are calling specifies these parameters to be 'reference' arrays, which means that the size and contents of these arrays can be different when the call returns. So you need to pass the address of a pointer that can be reallocated by the intermediate layer.