LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

how can I get structure pointer from labview?

Solved!
Go to solution
/*wrapper.h*/
#ifndef _WRAPPER_H_
#define _WRAPPER_H_

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

struct CPPLIBRARY_EXPORT cPlushandler;
typedef CPPLIBRARY_EXPORT struct cPlushandler cPlushandler_t;
CPPLIBRARY_EXPORT cPlushandler_t* createHandler();
void CPPLIBRARY_EXPORT deleteHandler(cPlushandler_t *m);
void CPPLIBRARY_EXPORT addElement(cPlushandler_t *m, int a);
int CPPLIBRARY_EXPORT getElement(cPlushandler_t *m, int index);

#ifdef __cplusplus
}
#endif

#endif // !_WRAPPER_H_


/*wrapper.cpp*/
struct cPlushandler { void *obj; }; cPlushandler_t* createHandler() { cPlushandler_t* m = NULL; m = (decltype(m))malloc(sizeof(*m)); if (m != NULL) { m->obj = new CPPLibrary(); } return; } void deleteHandler(cPlushandler_t *m) { if (m == NULL) return; delete static_cast<CPPLibrary *>(m->obj); free(m); return; } void addElement(cPlushandler_t *m,int a) { CPPLibrary *obj; if (m == NULL) return; obj = static_cast<CPPLibrary *>(m->obj); obj->setValue(a); return; } int getElement(cPlushandler_t *m, int index) { CPPLibrary *obj; if (m == NULL) return -1; obj = static_cast<CPPLibrary *>(m->obj); return obj->getValue(index);

 

1) Is it possible to create the cluster with void pointer?

2) I would like to call the  createHandler()  funcation and get the pointer of cPlushandler_t*?


0 Kudos
Message 1 of 9
(3,222 Views)
Solution
Accepted by topic author Y@sh001

Y@sh001 wrote:

1) Is it possible to create the cluster with void pointer?

2) I would like to call the  createHandler()  funcation and get the pointer of cPlushandler_t*?


1. Yes, but not in a way that's easily portable between 32- and 64-bit LabVIEW. Since the only element of the cluster is a pointer, in LabVIEW you can simply pass in a pointer-sized integer - in 32-bit LabVIEW that will be a U32, in 64-bit LabVIEW it will be a U64. If you really want you can wrap that pointer-sized value in a cluster but it's not necessary.

2. You don't show the createHandler function returning anything, but assuming it returns the right type, as suggested above you can simply treat it as a pointer-sized integer passed by pointer and let LabVIEW de-reference it for you.

Message 2 of 9
(3,174 Views)

Thank you for response nathand. Yes, createHandler() funcation is returning correct type "m". Let me try with int64_t*.

     

 

0 Kudos
Message 3 of 9
(3,164 Views)

Hi,

 

How can I pass that pointer to other function definition. Here I would like to pass the return value of createHandler() funcation in to addelement(). 

I try addElements() definition like below but none of them work correctly.
void  addElement(int64_t arg1, int64_t arg2);

void  addElement(int32_t arg1, int64_t arg2);

void  addElement(int32_t arg1, int32_t arg2);

void  addElement(int32_t arg1, int64_t arg2);

 

By doing pointer as first arguments labview program crash

void  addElement(int32_t *arg1, int32_t arg2);

void  addElement(int64_t *arg1, int32_t arg2);

void  addElement(int32_t *arg1, int64_t arg2);

void  addElement(int64_t *arg1, int64_t arg2);

 

Here the block diagram which I try
Capture.PNG

 

what is correct way to use that pointer in another function of library? 

0 Kudos
Message 4 of 9
(3,146 Views)

Hi,

 

How can I pass that pointer to other function definition. Here I would like to pass the return value of createHandler() funcation in to addelement(). 

I try addElements() definition like below but none of them work correctly.
void  addElement(int64_t arg1, int64_t arg2);

void  addElement(int32_t arg1, int64_t arg2);

void  addElement(int32_t arg1, int32_t arg2);

void  addElement(int32_t arg1, int64_t arg2);

 

By doing pointer as first arguments labview program crash

void  addElement(int32_t *arg1, int32_t arg2);

void  addElement(int64_t *arg1, int32_t arg2);

void  addElement(int32_t *arg1, int64_t arg2);

void  addElement(int64_t *arg1, int64_t arg2);

 

Here the block diagram which I try
Capture.PNG

 

What is correct way to pass the createHandler() function pointer to other function of Library?

0 Kudos
Message 5 of 9
(3,146 Views)
Solution
Accepted by topic author Y@sh001

What's the purpose of wrapping the object pointer into a cluster? Why not just do it like this:

 

/*wrapper.h*/
#ifndef _WRAPPER_H_
#define _WRAPPER_H_

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

 struct CPPLIBRARY_EXPORT cPlushandler;
 typedef CPPLIBRARY_EXPORT struct cPlushandler cPlushandler_t;
 CPPLIBRARY_EXPORT cPlushandler_t* createHandler();
 void CPPLIBRARY_EXPORT deleteHandler(cPlushandler_t *m);
 void CPPLIBRARY_EXPORT addElement(cPlushandler_t *m, int a);
 int CPPLIBRARY_EXPORT getElement(cPlushandler_t *m, int index);

#ifdef __cplusplus
}
#endif

#endif // !_WRAPPER_H_


/*wrapper.cpp*/
typedef void *cPlusHandler;

cPlushandler_t createHandler()
 {
	return new CPPLibrary();
}

void deleteHandler(cPlushandler_t o) {
	if (o != NULL)
	    delete static_cast<CPPLibrary *>(o);
	return;
}

void addElement(cPlushandler_t o, int a)
{
	if (o != NULL)
        {
               CPPLibrary *obj = static_cast<CPPLibrary *>(o);
	       obj->setValue(a);
        }
	return;
}

int getElement(cPlushandler_t o, int index)
{
	if (o != NULL)
        {
	    CPPLibrary *obj = static_cast<CPPLibrary *>(o);
	    return obj->getValue(index);
        }
        return -1;
}

Now you can configure the return value of createHandler()  to be a pointer sized integer and also all the class object parameters for all wrapper methods the same.

 

In fact you could even completely skip the declaration of cPlusHandler_t and just use CPPLibrary * everywhere instead. That would get rid of the static cast too. There is a use for static casts in C++ but LabVIEW does not care about C++ typesafety. For LabVIEW a pointer is a pointer is a pointer, if you get my drift. And LabVIEW does nothing with that pointer other than treating it as a 64-bit integer on the diagram and passing it as 32-bit or 64-bit integer on the stack to the DLL function when the parameter is configured as pointer sized integer.

 

If you want typesafety in LabVIEW you have to wrap this pointer into a LabVIEW object and create object methods that will call the DLL exports.

Rolf Kalbermatter
My Blog
Message 6 of 9
(3,116 Views)

Thank you rolfk, It work good I am able to access the C++ class object in LabView with help of your example code. 

  

"

In fact you could even completely skip the declaration of cPlusHandler_t and just use CPPLibrary * everywhere instead. 

"

Here you advise to remove the typedef cPlusHandler_t, and use the direct class type.  if I will do like that then my function definition will be look like below.

CPPLibrary* createHandler();
void deleteHandler(CPPLibrary*o);
void addElement(CPPLibrary*o, int a);
int getElement(CPPLibrary*o, int index);

 Function definition will take CPPLibrary* pointer. So I wanted to confirm with you 

void  addElement(intptr_t arg1, int32_t arg2);

will not create the issue while calling dll function 

void addElement(CPPLibrary*o, int a);

because of

"

LabVIEW does nothing with that pointer other than treating it as a 64-bit integer on the diagram and passing it as 32-bit or 64-bit integer on the stack to the DLL function. 

 

"


Thank you,

Yash
 

Message 7 of 9
(3,087 Views)

Yes you understood this correctly.

Rolf Kalbermatter
My Blog
Message 8 of 9
(3,081 Views)

Thank you.

-Yash

0 Kudos
Message 9 of 9
(3,076 Views)