LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Error 1097 from C-DLL (paho MQTT)

Solved!
Go to solution

Dear all,

 

I am sorry that this another topic about "DLL not working in LabVIEW" and "Get Error 1097 from DLL", but even after reading of maybe a dozen of these threads I got stuck now.

Within the project I am currently working on, I would like to test, if it is possible to use the paho MQTT C library from LabVIEW. We know that there are some "LabVIEW-native" implementations but a colleague of mine tested them some ago and mentioned that they all had different problems. So we thought that we should test the probably most widespread library (and actually the python version of it is already in use here).

 

Unfortunately the parameter list of the function in the dll I have problems with right now:

int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options);

is rather large, so I think it is a better idea to just upload my test project (LV2021-32 bit).

 

I have included the necessary header file (the function can be found in line 1424 with the defintion of the options parameter from line 1198 on and some examples for the options parameter from line 1383 ongoing - and even that here many parameters are NULL pointers this would be enogh right now).

 

At least the return value is now 0 (indicating that the dll execution should be fine?) but I get the famous error 1097 from it. So according to my understanding this is a memory management problem but I have to say that I have played with the parameters now for quite a while but without any progress so maybe it is time that somebody with more experience has a look.

 

So thanks a lot already and if you need more information (or if you don't want to download the project and it would be better if I copy parts of the header file and post it together with a screenshot of the VI) then please let me know.

 

Greetings Dennis

0 Kudos
Message 1 of 5
(379 Views)

From a first glance, serverURIs is passed as LabVIEW handle and binarypwd_len is a u8 instead of i32. That will not work.

 

I do not think you can interface to that library with any reasonable effort in pure LabVIEW. You are better off writing a wrapper.

 

You are using the async version. How are you going to implement the callbacks to get data back into LabVIEW?

0 Kudos
Message 2 of 5
(369 Views)

Hi,

 


@cordm wrote:

From a first glance, serverURIs is passed as LabVIEW handle and binarypwd_len is a u8 instead of i32. That will not work.


Oh yes, the binarypwd_len was wrong. But what do you mean with the serverURIs? I thought I copied it more or less from here.

For a test I have replaced the serverURIs now just with a U32-0 (NULL pointer) and corrected the binarypwd_len but I still get the error. I still would like to know the source of this problem, but maybe it is not needed anymore:

 


@cordm wrote:

 

I do not think you can interface to that library with any reasonable effort in pure LabVIEW. You are better off writing a wrapper.

 

You are using the async version. How are you going to implement the callbacks to get data back into LabVIEW?


Yes, you are absolutely right. I just have not thought about that.

So I guess the correct way would be to write a C dll which collects the returning answers (and everything else) in a queue or so and poll it from LabVIEW? (Or I think I have an example somewhere where a LabVIEW queue is passed to the dll for a similar purpose - I just have to check the C code for that).

 

And in that case, since I nevertheless have to go through the wrapper I can simplify the parameter list of the connect function from above.

 

So thanks a lot for bringing that up.

 

Greetings Dennis

 

 

 




0 Kudos
Message 3 of 5
(356 Views)
Solution
Accepted by topic author Tyri

@Tyri wrote:

Hi,

 


@cordm wrote:

From a first glance, serverURIs is passed as LabVIEW handle and binarypwd_len is a u8 instead of i32. That will not work.


Oh yes, the binarypwd_len was wrong. But what do you mean with the serverURIs? I thought I copied it more or less from here.

For a test I have replaced the serverURIs now just with a U32-0 (NULL pointer) and corrected the binarypwd_len but I still get the error. I still would like to know the source of this problem, but maybe it is not needed anymore:





You did, but then you put it in a cluster. Arrays in a cluster will be passed as LabVIEW handles and there is no way to turn that off. You would need to create another pointer, write your array into it and put the pointer in the cluster. That might be fine for a single function, but there are more nested structures in other functions.

 

 


@cordm wrote:

 

I do not think you can interface to that library with any reasonable effort in pure LabVIEW. You are better off writing a wrapper.

 

You are using the async version. How are you going to implement the callbacks to get data back into LabVIEW?


Yes, you are absolutely right. I just have not thought about that.

So I guess the correct way would be to write a C dll which collects the returning answers (and everything else) in a queue or so and poll it from LabVIEW? (Or I think I have an example somewhere where a LabVIEW queue is passed to the dll for a similar purpose - I just have to check the C code for that).

 

And in that case, since I nevertheless have to go through the wrapper I can simplify the parameter list of the connect function from above.

 

So thanks a lot for bringing that up.

 

Greetings Dennis





As far as I know, queues are not documented for external libraries. The way to go is to use user events by calling PostLVUserEvent. Knowledge Base: Provide a Callback Function Pointer to My DLL Using LabVIEW

In LabVIEW, you define a user event, pass it to the dll and call PostLVUserEvent with data matching the event. I am not sure how memory management works for that function. I allocate anything that is not a primitive with the Memory Manager functions ands dispose the handles after making the call. That seems to work.

 

You will need some way to get to the event refnums when the callback functions are called. The easy way is a global variable in the dll, but that is not thread-safe.

The callbacks get a pointer to a freely definable "object". That pointer is assigned in the connectOptions struct. Allocate a struct in your wrapper where you put the LVUserEventRefs (not their pointers!). You need to keep track of that pointer for the lifetime of the client and deallocate it when you free the client.

0 Kudos
Message 4 of 5
(340 Views)

Thanks a lot again. I certainly need some more time for debuging and optimizing but I think I am on a very good wy right now. 

 

Greetings Dennis

0 Kudos
Message 5 of 5
(269 Views)