04-19-2009 06:03 PM
Hi James,
I have reviewed the knowledge base, example code and your link.
The data being passed to my DLL is a struct of 3 arrays of 4225 elements of long integers. I think the solution is to pass the 3 arrays to the wrapper DLL and build the structure in the wrapper and then pass to my DLL. (the only problem is I don't have a C++ / VB compiler!)
Is that correct?
Is there an alternative purely LabVIEW solution?
regards
Al
04-20-2009 03:48 AM - edited 04-20-2009 03:49 AM
Al1234 wrote:Hi James,
I have reviewed the knowledge base, example code and your link.
The data being passed to my DLL is a struct of 3 arrays of 4225 elements of long integers. I think the solution is to pass the 3 arrays to the wrapper DLL and build the structure in the wrapper and then pass to my DLL. (the only problem is I don't have a C++ / VB compiler!)
Is that correct?
Is there an alternative purely LabVIEW solution?
regards
Al
In theory. In practice however it requires you to know a lot of things that a C compiler normally takes care about automatically. To explain it is also not really possible and to make it for you would be of little help really.
So go with the DLL wrapper! It is the best solution in terms of efforts, need of understanding low level details that should be things of the past when one wrote programs in assembly, and maybe most important maintainibility.
Rolf Kalbermatter
04-22-2009 06:17 AM
Hi AI,
Good afternoon and I hope your well today.
So I would like to take another look at this issue,
1) the dll has a custom structure which the import wizard breaks down in to 3 1D arrays, based on the header file information,
#define GRID_SIDE 65 // One side of the correction grid.
#define GRID_SIZE GRID_SIDE * GRID_SIDE // Grid is 65 by 65 values.
#define COUNTS_PER_GRID 1024 // 65 * 1024 values.
// Field distortion correction table format.
typedef struct _CORRTABLE
{
long XData[GRID_SIZE];
long YData[GRID_SIZE];
long ZData[GRID_SIZE];
} CORRTABLE;
Thus 3 1D arrays of size 4225. I am unsure why you would every have got 2D array - 65 by 65 array.. or maybe I miss read 65*65 by which you meant 1D array.
2) Why is it important for you to pass a cluster to the dll?
Cant use just created 3 1D arrays of size 4225 and configure the Call Library Function Node paramters XData, YData, ZData to Dimesions 1 and minimum size of4225?
3) The following article explains how you can pass Clusters/Structures to a dll being called from the Call Library Node.
How Do I Use Adapt To Type For Call Library Function Nodes?
http://digital.ni.com/public.nsf/allkb/3FF4805467498BA986256CB80082FED8?OpenDocument
Please let me know your thoughts,
04-22-2009 07:26 AM
Hi James,
1) the dll has a custom structure which the import wizard breaks down in to 3 1D arrays, based on the header file information,
#define GRID_SIDE 65 // One side of the correction grid.
#define GRID_SIZE GRID_SIDE * GRID_SIDE // Grid is 65 by 65 values.
#define COUNTS_PER_GRID 1024 // 65 * 1024 values.// Field distortion correction table format.
typedef struct _CORRTABLE
{
long XData[GRID_SIZE];
long YData[GRID_SIZE];
long ZData[GRID_SIZE];} CORRTABLE;
Thus 3 1D arrays of size 4225. I am unsure why you would every have got 2D array - 65 by 65 array.. or maybe I miss read 65*65 by which you meant 1D array.
I just put 65*65 to show why the import wizard had parsed incorrectly (a bug) and made a cluster of three arrays of size 65.
Cant use just created 3 1D arrays of size 4225 and configure the Call Library Function Node paramters XData, YData, ZData to Dimesions 1 and minimum size of4225?
I don't have control over the DLL (it's commercial) and it's expecting a structure of three arrays not three separate arrays.
2) Why is it important for you to pass a cluster to the dll?
I thought a struct such as this corresponds in LabVIEW to a cluster containing three arrays connected to the Call Library Function Node.
Looking at all the knowledge base / forum articles the solution is to place a wrapper DLL around my DLL so that the three arrays are exposed individually. i.e. I would have three connections to the Call Library Function Node of a simple array type (easy!)
I have a colleague writing a wrapper DLL for me and will post the results of testing.
I would prefer to use a LabVIEW solution so any help would be appreciated.
the "create .c file" from my Call Library Function Node for a cluster of three 4225 element arrays is as follows:
/* Call Library source file */
#include "extcode.h"
/* Typedefs */
typedef struct {
int32_t dimSize;
int32_t elt[1];
} TD2;
typedef TD2 **TD2Hdl;
typedef struct {
TD2Hdl elt1;
TD2Hdl elt2;
TD2Hdl elt3;
} TD1;
uint32_t MC_get_corrtable(uint16_t wSourceIndex, TD1 *pDestCorrectionTable);
uint32_t MC_get_corrtable(uint16_t wSourceIndex, TD1 *pDestCorrectionTable)
{
/* Insert code here */
}
I think this looks correct - but it causes a crash...
Thanks
Al
04-22-2009 12:56 PM - edited 04-22-2009 12:58 PM
Al1234 wrote:Hi James,
1) the dll has a custom structure which the import wizard breaks down in to 3 1D arrays, based on the header file information,
#define GRID_SIDE 65 // One side of the correction grid.
#define GRID_SIZE GRID_SIDE * GRID_SIDE // Grid is 65 by 65 values.
#define COUNTS_PER_GRID 1024 // 65 * 1024 values.// Field distortion correction table format.
typedef struct _CORRTABLE
{
long XData[GRID_SIZE];
long YData[GRID_SIZE];
long ZData[GRID_SIZE];} CORRTABLE;
Thus 3 1D arrays of size 4225. I am unsure why you would every have got 2D array - 65 by 65 array.. or maybe I miss read 65*65 by which you meant 1D array.
I just put 65*65 to show why the import wizard had parsed incorrectly (a bug) and made a cluster of three arrays of size 65.
Cant use just created 3 1D arrays of size 4225 and configure the Call Library Function Node paramters XData, YData, ZData to Dimesions 1 and minimum size of4225?
I don't have control over the DLL (it's commercial) and it's expecting a structure of three arrays not three separate arrays.
2) Why is it important for you to pass a cluster to the dll?
I thought a struct such as this corresponds in LabVIEW to a cluster containing three arrays connected to the Call Library Function Node.
Looking at all the knowledge base / forum articles the solution is to place a wrapper DLL around my DLL so that the three arrays are exposed individually. i.e. I would have three connections to the Call Library Function Node of a simple array type (easy!)
I have a colleague writing a wrapper DLL for me and will post the results of testing.
I would prefer to use a LabVIEW solution so any help would be appreciated.
the "create .c file" from my Call Library Function Node for a cluster of three 4225 element arrays is as follows:
/* Call Library source file */
#include "extcode.h"
/* Typedefs */
typedef struct {
int32_t dimSize;
int32_t elt[1];
} TD2;
typedef TD2 **TD2Hdl;typedef struct {
TD2Hdl elt1;
TD2Hdl elt2;
TD2Hdl elt3;
} TD1;uint32_t MC_get_corrtable(uint16_t wSourceIndex, TD1 *pDestCorrectionTable);
uint32_t MC_get_corrtable(uint16_t wSourceIndex, TD1 *pDestCorrectionTable)
{/* Insert code here */
}
I think this looks correct - but it causes a crash...
Thanks
Al
This only would work if the DLL was specifically written to use LabVIEW data types and since it is a commercial DLL this seems 200% unlikely.
Note that the structure contains three handles (a LabVIEW handle is a pointer to a pointer to a memory area specifically allocated with LabVIEW memory manager functions). Your DLL most likely accepts a structure with three pointers to a memory block and that is something completely different.
As I already told you doing what you want to do directly in LabVIEW while theoretically possible is VERY involved since you will have to write numerous VIs that will do things the C compiler normally does automatically.
The wrapper DLL is really the only feasable solution and also faster to develop and much more maintainable. You may doubt the faster argument since you may not know how to create such a DLL with a C compiler, but reality is that unless you can write such a DLL yourself you have really not a single chance to do it all in LabVIEW only, and many who can do the wrapper still wouldn't know how to do it in LabVIEW alone.
Rolf Kalbermatter
04-22-2009 02:22 PM
Rolf,
Great description - the NI descriptions don't make it so clear. I'll have a go with the wrapper DLL tomorrow and keep well away from the gruesome C / LabVIEW data structures!
Thanks for your help.
Al
06-04-2009 11:23 AM - edited 06-04-2009 11:30 AM
Hi,
This is the first time I've been able to spend some time on this problem for several months. Although the wrapper solution would work I don't have the knowledge to go down this route. My tame 'C' guru didn't believe that it would be necessary (after much slagging off of LabVIEW) He said due to the way 'C' stores arrays to just reserve the correct space and with the correct settings "it should work" - and it did!
see attachment.
Thanks for everyones help
Al
(just click on ignore when labview attempts to load winmcl32.dll)
06-04-2009 05:34 PM - edited 06-04-2009 05:42 PM
Well looking at it again I can see why this can work. The arrays in the structure are fixed size and as such not really pointers but simply inlined in the structure. So the structure has indeed a size of3 * 65 * 65 elements.
Rolf Kalbermatter