LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Efficient way to Pass and Receive Pointers with C/C++ DLLs from LabVIEW

Solved!
Go to solution

What is the best way to pass a handle by using dll programmed in Labwindows/CVI among Labview library call node?

 

I read a very helpful post on 

https://decibel.ni.com/content/docs/DOC-9080/version/5  about passing and receiving pointers with C dll in Labview.

 

However, my application is to interface Labview with a camera.  In the camera API, it defines 

#define void* CameraHandle

 

And then a variable CamHandle needs to be used by a bunch of other function.

 

In CVI, if not used as dll in Labview,  I would have

void OpenCamera()

{CameraHandle CamHandle;}

 

void SetParameter(CameraHandle CamHandle)

{

}

 

void CloseCamera(CameraHandle CamHandle)

{

}

 

If CamHandle is a void* type, how can I pass it from one node/function to the next in Labview when I use Call Library Function configuration?  In the post I read, it tell how to get the value the pointer points by using pointer to value and then dereferencing pointer.  However, what I need is to pass the pointer itself.  

 

Thank you very much!

 

Best,

Charles

0 Kudos
Message 1 of 20
(4,759 Views)

void * datatypes mean one of two things. It can be a universal pointer variable that allows different datatypes based on other parameters of your function that define the datatype the function should expect. Or it is a pointer to something you are not supposed to know and care about what is inside. API Handles generally fall under the second category.

 

In that case you simply configure the Call Library Node to use a pointer sized integer, by value if the datatype is void * and by pointer (reference) if it is void **.

Rolf Kalbermatter
My Blog
Message 2 of 20
(4,753 Views)

void OpenCamera()

{CameraHandle CamHandle;}

 

Because CameraHandle is defined as void* in the header file provided by the company, I think for this particular API, CamHandle is passed around as a void* type.  

 

In the first function, after I declare and initialize CamHandle, how am I able to pass it out.  It seems in Labview call library, only return and parameters can be used as input and output.  When I first initialize CamHandle in the first function, it's initialized as a local variable and I cannot return a void* type.  Or should I configure call library node to be (un)signed pointer-sized integer?  How can I know if it's signed or unsigned?

 

Another question:  how should I define the function?  Is below correct?

 

void DLLEXPORT *LoadDriverAndOpenCamera()

{CameraHandle CamHandle;

 return CamHandle;

}

 

Thank you very much!

0 Kudos
Message 3 of 20
(4,745 Views)

@soljiang wrote:

void OpenCamera()

{CameraHandle CamHandle;}

 

Because CameraHandle is defined as void* in the header file provided by the company, I think for this particular API, CamHandle is passed around as a void* type.  

 

In the first function, after I declare and initialize CamHandle, how am I able to pass it out.  It seems in Labview call library, only return and parameters can be used as input and output.  When I first initialize CamHandle in the first function, it's initialized as a local variable and I cannot return a void* type.  Or should I configure call library node to be (un)signed pointer-sized integer?  How can I know if it's signed or unsigned?

 

Another question:  how should I define the function?  Is below correct?

 

void DLLEXPORT *LoadDriverAndOpenCamera()

{CameraHandle CamHandle;

 return CamHandle;

}

 

Thank you very much!


Well, most likely you have a typo in your code. This is more likely what you want to have as your OpenCamera function

 

CameraHandle DLLEXPORT LoadDriverAndOpenCamera()
{
    CameraHandle CamHandle;
    // Do something to initialize CamHandle!!!
    return CamHandle;
}

 

With CameraHandle being defined as void* this results in: 

 

void* DLLEXPORT LoadDriverAndOpenCamera()
{
    CameraHandle CamHandle;
    // Do something to initialize CamHandle!!!
    return CamHandle;
}

 

Which is something quite different from:

 

void DLLEXPORT *LoadDriverAndOpenCamera()

 

If you consider what I wrote in the first post you will simply configure the return value of this function to be a pointer sized integer.

 

The question if you should treat a pointer as unsigned or signed pointer sized integer is mostly academic. I prefer unsigned, since negative pointers sound strange to me, but it doesn't really matter, as long as you are consistent with it throughout your entire VI library for any particular handle type.

Rolf Kalbermatter
My Blog
Message 4 of 20
(4,736 Views)

Thank you very much.  

I saw you replied to a post http://lavag.org/topic/16638-header-and-dll-dont-reconize-fonction/

 

I have a question related when I'm using labwindows/CVI on 32-bit window 7.

 

I declared variable with type uint64, unsigned __int64 and unsigned long long.  They should be equivalent, but all of them gives me error message when compiling.  It says unrecogized statement and the error points to my declaration:  

 

unsigned __int64 exposure; 

 

The error says:  

113, 5 Unrecognized statement.

113, 14 syntax error; found 'long long' expecting '}'.

114, 19 syntax error; found '(' expecting ')'.

 

I included 

#include <stdint.h>

#include<userint.h>

 

Am I still missing something?  

0 Kudos
Message 5 of 20
(4,728 Views)

I didn't turn on Buld with C99 extensions.  Now seems it solved that particular problem.  Thanks!

0 Kudos
Message 6 of 20
(4,724 Views)

__int64 is a MSC specific datatype. Possibly CVI implements that too, since it tries to be compatible with MSVC in many areas but strictly speaking it is a MSC anachronisme. The official type is "long long" since C99 as you have found out, and didn't officially exist before. (u)int64 is a LabVIEW datatype and as such would be recognized by CVI if you  would compile C code where you include the LabVIEW extcode.h header file (and define a specific preprocessor define to enable the old LabVIEW specific datatypes for backwards compatibility if you use the headers from a recent LabVIEW version).

 

Last but not least there is (u)int64_t which is the official ANSI C type. Don't even get me started on the about a dozen Windows API variants Smiley Very Happy

Rolf Kalbermatter
My Blog
Message 7 of 20
(4,718 Views)

Hi, I still have problems with passing the handle.

 

QCam_Handle is defined as void*

 

int main ()
{ QCam_Handle handle;
handle=LoadDriverAndOpenCamera();
SetParameter(handle, exposure);
ReleaseDriverAndCloseCamera(handle);
return 0;
}

 

QCam_Handle LoadDriverAndOpenCamera()
{ QCam_Handle handle;

QCam_OpenCamera(cameraList[0].cameraId, &handle);

return handle;
}

 

When I use handle by calling 

void SetParameter(QCam_Handle handle, uint32_t exposureTimeMillisecond)

 

After I build exe file, everything turns out fine.

 

 

Then I use same functions but I need to build dll, the handle is not passed on correctly.

 

In labview library call, I configured LoadDriverAndOpenCamera() return value to be numeric, unsigned pinter-sized integer.

 

then for SetParameter, I set arg1 to be Adapt to Type,  NOT constant, Handles by value.   But functions in SetParameter() can't use handle that's passed on by LoadDriverAndOpenCamera().

 

What did I do wrong? 

 

Thank you very much!

 

0 Kudos
Message 8 of 20
(4,625 Views)

Please read the documentation. When you select "Adapt to Type", scalars are passed by reference. The function prototype indicates that the Handle parameter should be passed by value. So you should make the QCam_Handle parameter a pointer-sized integer passed by value.

0 Kudos
Message 9 of 20
(4,614 Views)

numeric, unsigned pinter-sized integer was exactly what I set the paramater to be.  

0 Kudos
Message 10 of 20
(4,609 Views)