LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DLL Wrapper doesn't succeed to call a DLL function

Hi,

I'm currently interfacing an optris camera with Labview. My program work well, for now. I'm actually trying to use an external signal to trigger a snapshot (electric circuit link to the camera). For that I need to use a fonction of the dll given by Optris (ImagerIPC2.dll), its name is GetFrame, here  is it's definition on the header :

 

IMAGERIPC_API HRESULT WINAPI GetFrame(WORD index, WORD timeout, void *pBuf, unsigned int  Size, FrameMetadata *pMetadata);

 

with pMetadata define as :

struct FrameMetadata

{

    unsigned short Size;    // size of this structure

    unsigned int Counter;    // frame counter

    unsigned int CounterHW;    // frame counter hardware

    long long Timestamp;    // time stamp in UNITS (10000000 per second)

    long long TimestampMedia;

    TFlagState FlagState;

    float TempChip;

    float TempFlag;

    float TempBox;

    WORD PIFin[2];           

    // DI = PIFin[0] & 0x8000

    // AI1 = PIFin[0] & 0x03FF

    // AI2 = PIFin[1] & 0x03FF

};

 

As you can easily understand, Labview really don't understand the metada struct. So I am trying to do a wrapper dll to just obtain the information that I need ( underlined on the struct : WORD PIFin[0] in order to have the digital input). So I already did it  (see in attached file),  it's the function : PIFvalue; the two others were to test my dll. So now is my problem :

 

My dll work because i can use my function add. But when i try to use PIFvalue, I don't succeed to call correctly the function getFrame so at the end *pif= NULL and i don't have what i expect. I don't use to do dll wrapper, so my way to call the function or to use it may be wrong!

Have you a better way to call the function? or may be a correction for my program?

 

Thanks by advance for your help,

Alexandre Blouin.

PS : I don't join the dll ImagerIPC2.dll because you need the camera in order to use it.

0 Kudos
Message 1 of 6
(4,366 Views)

In your code, you have:

if (*pif==NULL)
{
*pif=5;
}
return *pif;

 

So you shouldn't get null.

 

Add more error check in your code.

If your have the lib file, you can try static link to the dll, instead of LoadLibrary.

Show us your VI.

 

 

 

George Zou
0 Kudos
Message 2 of 6
(4,318 Views)

There is absolutely nothing inherently impossible to do directly in a LabVIEW VI about this metadata structure. There are no pointers as far as I can see, and the only uncertainity is that enum TFlagState as there is an uncertainity about its integer size. Most likely the C compiler will have used an uInt32 for that, but it could also be an uInt8 since the enum values itself fit easily into a char type.

The only other problem you will have when trying to create this structure in LabVIEW through a cluster is that you will have to watch out for alignment issues. Basically LabVIEW tends to pack clusters to the smallest possible memory representation at least on the x86 platform. Most C compilers align elements inside structures to their natural size. This means for instance that you would have to add a dummy int16 into the LabVIEW cluster between the "Size" and the "Counter" element since Counter is a 32 bit value and therefore the compiler will have it aligned to a 32 bit offset relative to the start of the structure.

The element PIFin is simply a fixed size array, this means the C compiler will simply inline it in the structure and NOT place a pointer to an array into the structure, so you can represent it with two uInt16 values in the cluster.

Then configure that parameter as Adapt To Type and wire the cluster wire to it.

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 6
(4,313 Views)

thanks for your answers and sorry I forgot to put the definition of TFlagState

 

enum TFlagState {fsFlagOpen, fsFlagClose, fsFlagOpening, fsFlagClosing, fsError};

 

I tried to follow your instruction. The result is in attached file. I tested it but it didn't work.

I think that my definition of pBuff is wrong ( i defined it as adapt to type, and i put in input an array of string because it normally sends me the buffer of the camera) or that can be also the dummy, i must have not understoodd well what i was supposed to do for the memory representation's problem.

Thanks for your helps.

Alexandre Blouin.

0 Kudos
Message 4 of 6
(4,282 Views)

Well, two problems with your VI for sure:

 

1) While the enum might be 8 bit or 32 bit, the float that follows is a 32 bit entitiy and as such it will need to be aligned to 32 bit just as with the Counter element. So for now I would make the enum a 32 bit value and eventually deal with an AND mask of 0xF to make sure no garbage might be getting back from the function. Also this makes the structure 3 bytes to small, which if the function ends up writing values in the last two "array" elements rather than reading them, might cause a memory corruption.

 

2) VERY VERY TERRIBLY BAD!!!!!!!!!! causing a crash for sure rather sooner than later:

You pass in an empty array of strings as buffer! And configure it as an Adapt to Type parameter. This will pass in a LabVIEW array handle of zero string handles with the length null. That will result in a pointer to a pointer to a 4 byte length of 0 being passed to the function.

Unless your DLL function was EXACTLY written for LabVIEW and expects EXACTLY this datatype, you can be sure that it will go wrong. Since the DLL was not written for LabVIEW this definitely has to go away.

To add insult to injury you tell the function that the array you pass in contains enough space to store 220032 elements (maybe that are bytes, but it could be anything else depending what the function description documents).

So the function will try to go and write into that buffer that you told it to contain 220032 elements. Only there is really a pointer (4 or 8 bytes only to a 4 byte area) and your function will write into that buffer of 4 or 8 bytes not only overwriting the pointer in there but also lots of other memory it has absolutely no business to even try to access and in the process also trash the LabVIEW handle. If that doesn't immediately bail out with an error 1097 because LabVIEW detected some memory access exception during the call of the function, it will definitely go havoc as soon as LabVIEW tries to clean up the handle which your function so thoroughly destroyed.

 

Without knowing the actual function declaration and a well written documentation about the function parameters it is not really possible to give you a conclusive answer as to how this parameter should be configured in LabVIEW. It is possible that the function expects there a buffer of Size bytes (or words, or longs, or some arbitrary structs). If it would be an array of Size scalars you have to Initialize Array an according array with Size elements, configure the parameter to be of type Array of subtype <your scalar element type> passed as a C Array Pointer and connect the initialized array to the left side of the parameter. On return of the function the array should contain the data that the function has filled in.

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 6
(4,262 Views)

Thanks for your help.

I put the enum in 32 bit, and i tried different types as buffer but i always had error 1097. I will ask more informations to the producer and post an other message.

Alexandre Blouin.

0 Kudos
Message 6 of 6
(4,241 Views)