Jump to content
viSci

Call Library Function Exception Error

Recommended Posts

Was hoping someone might be able to give me a tip on this one...

Trying to call the function below:

typedef struct
{
    unsigned int  Length;
    unsigned int  Id;
    unsigned int  TimeTag;
    char    Data[1024];
}DATA_FRAME;


int __stdcall SRVIVR_API_StoreData(void* handle, int partition,  int totalFrames, DATA_FRAME frameData[]);

Here is what the import dll tool produces:

1.png

This does not look correct to me and produces the dreaded 1097 exception error.

I modified the call to be:

2.png

Which I believe is closer to the intent of the original C function, but still gives me a 1097 error.  I suspect

that somehow the array pointer that the function is expecting is not correct.  The frameData parameter is being passed

into the function as a 'Adapt to Type', Array Pointer.  I also tried flattening to a single U32 array and passing that in as an array data type but still no joy.  Any ideas?

BTW, I have had success calling many other functions from the dll of the form:

int __stdcall func(void* handle, int param1,  int param2, etc);

Edited by viSci

Share this post


Link to post
Share on other sites

Whether you have separate elements or a cluster or a 1D array of clusters with a single element should probably not matter, as they are all the same in memory. I'm pretty sure the part you're missing is the char    Data[1024]  line - this means an array of 1024 bytes is expected (possibly so that it can be written into) and you're not allocating that memory. Try initializing the array to a size of 1024 bytes.

Share this post


Link to post
Share on other sites

Ok, that comment prompted me to dig some more into the IDD for the device and found that Length parameter, which I thought was the number of bytes in the data array is really the number of bytes in the data array plus 12 for the 3 long int parameters in the cluster.  Once I made that change it all started working.

Thanks for your help!

Share this post


Link to post
Share on other sites

Yes, Yair's idea won't work. The array inside the cluster is fixed size and therefore inlined. Putting a LabVIEW array in there is not only once wrong but even twice. First a LabVIEW array is not just a C array pointer but really a pointer to a pointer to a long pascal byte array, second there is not an array pointer but an inlined fixed size array in the structure.

So the correct thing to pass is a byte array of 1024 + 12 bytes as you have already figured out. And more correctly it might be actually totalFrames * (12 + 1024) bytes.

Also eventhough you may not plan to ever use this in 64-bit LabVIEW it still would be useful to configure the handle parameter as pointer sized integer instead (and use a 64 bit integer control on the front panel to pass that handle around in the LabVIEW diagrams).

 

Edited by rolfk

Share this post


Link to post
Share on other sites

So does every *struct passed into a dll need to be flattened to a byte array? I guess in the previous case it only worked because I was passing a empty array in the cluster.

So for something like this:

 

// Structure to pass reconstruction parameters
struct RECON_INFO_STRUCT
{
    unsigned int        cpmBlkSize;
    unsigned int        sepTimeDelta;
    unsigned int        sepByChannelFlag; //0=no, 1=yes
    unsigned int        wavFormat; //0=mulaw, 1=pcm
    unsigned int        decryptFlag; //0=no, 1=yes
    unsigned int        AESKeySize; //0=128,1=192,2=256
    char                      AESKey[CRYPTO_KEY_MAX_LENGTH_BYTES];
    unsigned int        makeReadableAfterReconFlag;
    char                      reconFile[MAX_PATH];
};

STATUS __stdcall SRVIVR_API_ReconFile(void* handle, char* partDataFileName, RECON_INFO_STRUCT* pReconInfo, void* pNotifyCB, void* pCBArg);
 

Do I need to manually flatten everything to a single byte array or is there some way to use this?

struct.png

Edited by viSci

Share this post


Link to post
Share on other sites

Well every structure can be of course represented by a byte array. But you don't always have to go through those trouble. Fixed arrays inside a structure are in fact best implemented as an extra cluster in LabVIEW inside the main cluster with the number of elements indicated between the square brackets and of the type of the array.

BUT: if the number of elements get huge this is not practical anymore as you end up with mega pronto saurus clusters in LabVIEW. Then you have two options:

1) flatten the entire cluster into a byte array and before the call insert into (for input values) and after the call retrieve the elements by indexing into that array at the right offset. Tedious? Yes you bet! And to make everything even more fun you also have to account for memory alignment of elements inside the cluster!

2) Create a wrapper DLL in C that translates between LabVIEW friendly parameters and the actual C structures. Yes it is some work, and requires you to know some C programming but in fact less low level knowledge about how a C compiler wants to put the data into memory than the first approach. 

Edited by rolfk

Share this post


Link to post
Share on other sites

I like the idea of a cluster within a cluster.  Is it then possible to just use an array to cluster going into a cluster bundle to add in the fixed arrays?

Share this post


Link to post
Share on other sites

The other option is to create a cluster of 1024 int8 values and use that for the inlined char array.

Share this post


Link to post
Share on other sites
52 minutes ago, viSci said:

I like the idea of a cluster within a cluster.  Is it then possible to just use an array to cluster going into a cluster bundle to add in the fixed arrays?

Nope! Array to Cluster is limited to 256 elements in its Right click popup menu.

Of course you could add 4 clusters of 256 bytes each directly after each other.

Edited by rolfk

Share this post


Link to post
Share on other sites
49 minutes ago, Aristos Queue said:

The other option is to create a cluster of 1024 int8 values and use that for the inlined char array.

You like mega pronto saurus clusters, don't you! :o :D

Edited by rolfk

Share this post


Link to post
Share on other sites

Not sure were the 1024 comes in as AES key here is 32 bytes and the ReconFile path is 260 characters.  As you said to get 260 I would have to append two clusters.

Here is my latest clusterasaurus...

image.png

Unfortunately this still is not satisfying the DLL.  It is not blowing up but returning an error indicating an invalid parameter so I might not be too far off...

Share this post


Link to post
Share on other sites

Finally, It works!  Sometimes a clusterasaurus is just what you need.  The cluster within cluster idea is a neat trick, thanks Rolf.

Share this post


Link to post
Share on other sites
On 3/16/2018 at 3:05 PM, rolfk said:

Yes, Yair's idea won't work.

The funny thing is that I actually ran into this myself more than once, but I keep forgetting that it's not like flattening the array using the LV flattening functions and that you need to inline the bytes yourself using a cluster. I seem to recall making that mistake more than once and then having to fix it after testing.

Share this post


Link to post
Share on other sites
On 3/16/2018 at 11:13 AM, rolfk said:

You like mega pronto saurus clusters, don't you! :o :D

No, but it is an option, and sometimes when talking to a foreign language, it is better to bow to the grammar of the foreign language than to cleave to the proper grammar you might normally use.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.