LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Can LabVIEW make use of an OCX (ActiveX) "Pointer to Array"?

Here is the one example relating to this from the C++ SDK (attached):

4.7.24 LockForRead
Prototype
virtual CyResult LockForRead( void ** aPtr, unsigned long* aSize, unsigned long aFlags = 0 );
Description
Locks a buffer for read operations.
This function blocks and waits for data to be available, unless otherwise indicated by the flags
Parameters
aPtr - A pointer to the pointer that will point to the data in the buffer
aSize - A pointer to an unsigned long integer that will contain the size of the buffer.
aFlags - Possible flags that can be use in combination:
FLAG_NO_WAIT - If an image is already available, don’t wait for the next.
FLAG_ERROR_IF_EMPTY - If no image is available and no writing operation is pending, return an error.
If this flag is not present, the function waits for the next write operation.



4.7.31 Example - Locking for read
#include CyBuffer.h

CyBuffer lBuffer( 1024 );
CyResult lResult;
unsigned char * lData;
unsigned long lSize;

// ... give the buffer to a object that will fill it

// Now, we want to wait for data and then use that data
// The function uses a void** pointer, we use an unsigned
// char* pointer because it is more convenient to use.

lResult = lBuffer.LockForRead( (void**) &lData, &lSize, 0 );

// Error Handling

// Here the data is locked and will not be overwritten by
// any other thread.
// ... use the data …

// When the data is not needed anymore, release it
lBuffer.SignalReadEnd();


While this bit looks simple enough, there is a lot that needs to go on to get to the point where this call can be made. In the LabVIEW code screenshot I sent, the LockForRead step uses the sixth of six refnums that need to be opened and configured to get to that step where the camera is up and running and making data available. I'm not sure how much of that setup must be duplicated within the DLL as well. I would guess it would include at least as much as the setup of "lBuffer" as well since the C++ code does not seem to use anything that looks like a LabVIEW refnum...

This example would seem to relate to that "lBuffer" setup process:
6.1.7 Example - Setting the capacity

#include CyBuffer.h
#include CyPixelTypeFactory.h
#include CyImageBuffer.h
#include CyPixelType.h
#include CyGrayscale8.h

CyImageBuffer lBuffer;

// Now set the capacity
lBuffer.SetCapacity( 640, 480, CyGrayscale8::ID );

// This is the equivalent to the following code with a normal CyBuffer
CyBuffer lBuffer2;
CyPixelType*
lType = CyPixelTypeFactory::CreatePixelType( CyGrayscale8::ID );
lBuffer.SetCapacity( lType.GetBufferSizeFor( 640, 480 ) );
delete lType;

Message Edited by Warren Massey on 03-13-2005 04:45 AM

0 Kudos
Message 11 of 32
(2,661 Views)
Attached is a more complete example of how an application to read the camera is built under C++. This particular code comes as part of an installer package for a "Cam2Net" adapter that Pleora makes & JAI/Pulnix rebrands and sells (we're actually using a Pulnix camera for our work here). The links to the installer are also included in the zip file. If you want to see what's in the full package, I suggest you get it and run the installer. It has been harmless and easily unsinstalled on the 4 different PC's I've used it on. SDK docs are in there as well.
0 Kudos
Message 12 of 32
(2,659 Views)
Hello Warren,

Looking through the documentation it appears as if the pointer function may only be available for the C++ SDK and left for compatibility reasons in the ActiveX interface. Could you confirm with the manufacturur that the pointer function works with ActiveX?

Regards,

Matt F
0 Kudos
Message 13 of 32
(2,598 Views)

@matt F wrote:
Hello Warren,

Looking through the documentation it appears as if the pointer function may only be available for the C++ SDK and left for compatibility reasons in the ActiveX interface. Could you confirm with the manufacturur that the pointer function works with ActiveX?

Regards,

Matt F




OK, I asked Pleora "Does it work under OCX?" and their reply was:





Indeed it does work. Because of the performance degradation when using a
SAFEARRAY with LockForRead, we created the LockForReadPtr which returns
a pointer to the buffer so that people using Borland C++ or Delphi can get access
directly to the region of memory.

Unfortunately there is nothing we can do with such pointer in Visual Basic
unless we create a COM/ActiveX component to access memory directly given
that pointer.


0 Kudos
Message 14 of 32
(2,588 Views)
Similar to Visual Basic, LabVIEW does not have the ability to work directly with pointers. You will not be able to directly access the memory referenced by this pointer in LabVIEW.

By creating a DLL in C++ or another language that can easily manipulate memory pointers it will be possible to copy the data in the array into an array that was allocated by LabVIEW.

This function in the DLL will need to read the pointer from the ActiveX object, and also take an as input an array. This array input will come from LabVIEW. The array input will be allocated in LabVIEW using the Initialize Array function, or by wiring to a control which is initialized to the proper size.

The function should then copy the data reference by the pointer to the array input from LabVIEW, and then deallocate the pointer returned by LockForReadPtr.

This will allow the data to be copied into LabVIEW allocated memory where is can be used as any normal LabVIEW array.

Scott Y
NI
0 Kudos
Message 15 of 32
(2,571 Views)
So why can't LabVIEW, which already has the ActiveX object open, request the pointer and then pass it down into the DLL which would actually use it? Why must the DLL also open its own copy of the ActiveX object? (Not nearly so easy to do in C++)
0 Kudos
Message 16 of 32
(2,574 Views)
As a pointer is nothing than 32-bit integer, there is no reason why you can't pass it from LabVIEW to the DLL. If that is easier for your application, I would suggest starting there. This is assuming that this pointer can be refernced in the memory space of the application calling the ActiveX method, as Pleora indicated.

Scott Y
NI
0 Kudos
Message 17 of 32
(2,567 Views)
At this point I'll refer you back to message 6 of this thread because we seem to have come full-circle at this point.
0 Kudos
Message 18 of 32
(2,628 Views)
The errors you have been seeing are most likely caused by your DLL trying to access a pointer which is invalid in its memory space. It is very unusual that a pointer is returned from an ActiveX object for this very reason.

When this pointer is returned from the SDK version of your driver it can be used directly. When returned by the ActiveX object one way this pointer can be referenced by your DLL is if it first goes through a process called Marshaling to allow the DLL access to the ActiveX object's memory space. It appears that this marshaling has not been implemented. If you have any C/C++ examples that show how to use the pointer returned from the ActiveX object, it should demonstrate how to Marshal the data.

If you do not have any examples, the two links below will give you some additional information on what is involved when you need to Marshal data between two memory spaces.

http://www.microsoft.com/msj/0296/activex0296.aspx

http://msdn.microsoft.com/msdnmag/issues/0900/DataTrans/default.aspx

As you can see this is not a trivial project. Also, as there is additional overhead associated with the communication between the different memory spaces, you will not see all the gains you would if this was a pointer used exclusively in the same memory space.

From what I understand, obtaining a pointer to your array that can be used in the most efficient way possible is your number one goal. If that is true, I would recommend using the SDK version of your driver, and avoid ActiveX entirely. This will allow you to obtain a pointer to your data array without going through the marshaling process and without using Variants.

Scott Y
NI
0 Kudos
Message 19 of 32
(2,605 Views)
Thanks for the clear explanation and the pointers to the other documentation. I'll see what can be done within the SDK.
0 Kudos
Message 20 of 32
(2,594 Views)