-
Posts
26 -
Joined
-
Last visited
-
Days Won
4
Łukasz last won the day on August 29 2023
Łukasz had the most liked content!
Profile Information
-
Location
Wroclaw
LabVIEW Information
-
Version
LabVIEW 2020
-
Since
2012
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
Łukasz's Achievements
-
Pass complex data structure to C function
Łukasz replied to Łukasz's topic in LabVIEW Community Edition
Thank you @Rolf Kalbermatter. Your suggestion works as expected, and the code is much simpler than in the previous version. As I understand it, performing the opposite operation would not be easy since we can't resize the array. I wonder if there is any other function to allocate memory on the C side using LabVIEW, or if `NumericArrayResize` from extcode.h is the only option? -
Pass complex data structure to C function
Łukasz replied to Łukasz's topic in LabVIEW Community Edition
Thank you for your reply, passing a struct seemed very intuitive, and I considered a similar approach. However, I couldn't find any examples of how to pass an array of structs, which is the main blocker for this idea. Have you seen this approach used anywhere? -
I need help passing a complex data structure — a map of clusters containing an enum type and a string value — to a C function. My initial solution was to convert this structure to a string and then to byte buffer, pass the buffer and its lenght, and then decode it on the C side. However, this approach has issues when the key or value contains characters that I used as separators. While I could improve my encoding method, I'm looking for alternative solutions to achieve my goal. Function prototype: int32_t lv_amqp_basic_publish(int64_t *conn_int, uint16_t channel, CStr exchange, CStr routingkey, uint8_t *headersBuffer, int32_t headersBufferLen, LStrHandle messagebody, LStrHandle error_description); headersBuffer is used to populate headers table (array of amqp_table_entry_t_): typedef struct amqp_table_entry_t_ { amqp_bytes_t key; /**< the table entry key. Its a null-terminated UTF-8 * string, with a maximum size of 128 bytes */ amqp_field_value_t value; /**< the table entry values */ } amqp_table_entry_t; LabVIEW code to encode headers map to string: The blue arrow represents the encoding signature for each element The green arrow indicates an issues with this method and ugly workaround I can modify both the LabVIEW and C code. Any suggestions would be greatly appreciated.
-
I tried all the solutions using LabVIEW 64-bit on Ubuntu. I fixed case 2, and cases 5 and 6 produced very similar results. I'm a bit worried about using BLAS VIs because they might cause problems during the building process. @cordm and @LogMAN I truly want to express my gratitude for your help.
-
oh true, the frame is 16 bytes long. So your solution is the fastest now.
-
Your task is whipping up a piece of code that can unravel a string stuffed with uint64 data, all dressed up in that fancy communication protocol jacket. But hold your horses, partner! The catch is to make it faster than my own fancy footwork. Giddy up and get coding! Example of slow solution: Much faster solution: Y'all can lay your eyes on the testin' stuff right down yonder in that there attachment. And guess what? There's a little description of that frame thingamajig to tickle your fancy. So put on your explorin' hat and give it a gander! decode-frame.vi
-
I investigate that topic two years ago, and there was no easy CANopen solution for LabVIEW. Low cost solution can include kvaser hardware, but you will need to implement CANopen layer by yourself. Very high cost, but realy good and flexible is solution which includes vector hardware + vector Canoe envirement that easly share variables with LabVIEW. However I think this solution is for long term project and CANoe enginner will be required to set up the envirement. I will also check the oportunity to use python library for example: https://canopen.readthedocs.io/en/latest/ so you will trigger python script from LabVIEW.
-
Regarding which port was used it should be possible to get that information from winsock library on Windows. I think the answer can be found here: https://forums.ni.com/t5/LabVIEW/Is-it-possible-to-extract-the-local-port-associated-with-a-TCP/td-p/459672
-
So I removed the defualt version of libzmq3-dev package from Ubuntu and installed manualy the version with draft api enabled (for Ubuntu 20.4) echo 'deb http://download.opensuse.org/repositories/network:/messaging:/zeromq:/release-draft/xUbuntu_20.04/ /' | sudo tee /etc/apt/sources.list.d/network:messaging:zeromq:release-draft.list curl -fsSL https://download.opensuse.org/repositories/network:messaging:zeromq:release-draft/xUbuntu_20.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/network_messaging_zeromq_release-draft.gpg > /dev/null sudo apt update sudo apt install libzmq3-dev That fixes the problem and the basic functions ZMQ LabVIEW library works.
-
Thank you for your response. I see this topic will be more and more interesting. So in relation to that Call Function Node doesn't find the library you suggest that libzmq cannot be found by ELF file (The question is: which one when I run vi in LabVIEW ide? just ./labview ?). But ok, not best but "a test" will be to check if the default loader can find dynamically load library (libzmq) which is used by the wrapper (lvzmq64.so) /usr/local/natinst/LabVIEW-2020-64/vi.lib/addons/zeromq$ ldd lvzmq64.so linux-vdso.so.1 (0x00007fffac9f1000) libzmq.so.5 => /lib/x86_64-linux-gnu/libzmq.so.5 (0x00007f3034e3e000) liblvrt.so.20.0 => /usr/local/lib64/liblvrt.so.20.0 (0x00007f303315a000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3032f68000) ... so we are sure that it could be found (we know that it could be found in ld-cache because we checked it with ldconfig in previus post). However, that doesn't mean that EFL file can find it, because NODEFLIB flag could prevent that. *I have checked if ./labview has set this flag, but no. No response - it's off. But as I wrote before I am not sure if this is a real caller of wrapper library. $ readelf -d ./labview | grep NODEFLIB Another option where EFL file will look for the library is LD_LIBRARY_PATH and RPATH / RUNPATH. Changing LD_LIBRARY_PATH is not good practice but I have to checked it: export LD_LIBRARY_PATH=/lib/x86_64-linux-gnu/ which looks silly, doesn't change anything but I feel better that I've checked all ideas. RPATH and RUNPATH are set on compilation porcess, so I cannot change them easly. At this point, I cant see any problem that libzmq cannot be find as a resource. I think the issue is in wrapper itselfs, what is shown by this simple c app test.
-
Hello, I'm tring to make zmq package (https://sourceforge.net/projects/labview-zmq/) work on Linux Ubuntu 20.04. VIs api in this package relates on shared library creating in c and are builded for Windows but not for Linux. However we can find sources as well as a few tips how to build this library. $ ls bonzai.c debug.c makefile rename_calls.vi win32 zmq-errors.txt bonzai.h debug.h parse_errnos.py rename_lib2.vi win64 zmq_labview.c where zmq_labview.c is our main source file which could be build with makefile. As a source of knowledge I used Brandon Jones post on forum about how to build this package for NI Linux RT: https://sourceforge.net/p/labview-zmq/discussion/general/thread/d5d0b49987/ However, after many hours spend I sill getting error 13 when I tring to call this library from LabVIEW. Following steps show what I have tried, however in every step I could make a mistake as I'm not regular C programmer. ___________________________________________________________________________________ The first step is to check if two librarys which are needed by zmq_labview.c are avaiable in system: libzmq.so $ ldconfig -p | grep libzmq.so libzmq.so.5 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzmq.so.5 libzmq.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libzmq.so liblvrt.so (I dont undestant why its needed as its not included in zmq_labview.c but its used in makefile) $ ldconfig -p | grep liblvrt.so liblvrt.so.20.0 (libc6,x86-64) => /usr/local/lib64/liblvrt.so.20.0 liblvrt.so.15.0 (libc6) => /usr/local/lib/liblvrt.so.15.0 liblvrt.so (libc6,x86-64) => /usr/local/lib64/liblvrt.so NOTE: this output is from system where I didn't modyfied /etc/ld.so.conf.d. I have tired to add new file with paths to liblvrt.so as Brandon Jones describes, but I didn't recognized any difference. Next step is to modify source, so I set: #define LVALIGNMENT 8 and pthread_t thread; And then makefile modyfications are needed. I have simply removed all windows realted stuff and thats a result: # LVZMQ GNU-MAKE BUILD SCRIPT # for both Windows and Linux targets SRC = zmq_labview.c # LINUX BUILD RULES # omg so much simpler! LABVIEW = /usr/local/natinst/LabVIEW-2020-64 LDFLAGS = -L $(LABVIEW) -L /lib/x86_64-linux-gnu/ CFLAGS = -Wall -O3 -fpic -I $(LABVIEW)/cintools -I $(LABVIEW) LDLIBS = -lzmq -llvrt ifdef DEBUG CFLAGS += -DDEBUG endif all : lvzmq64.so # copy the product to the labview directory @cp $< $(LABVIEW)/vi.lib/addons/zeromq # Linux shared-library target lvzmq64.so : $(SRC) $(CC) -shared -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LDLIBS) running make gives this results: In file included from bonzai.h:29, from zmq_labview.c:12: bonzai.c: In function ‘bonzai_grow_leaf’: bonzai.c:74:2: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation] 74 | for ( i = 0; i < tree->n; ++i ); | ^~~ bonzai.c:76:3: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘for’ 76 | if (( t = tree->elem[i] ) && ( t->id == x )) | ^~ zmq_labview.c: In function ‘lvzmq_close’: zmq_labview.c:108:11: warning: variable ‘i’ set but not used [-Wunused-but-set-variable] 108 | int ret, i; void *sock; | ^ zmq_labview.c: In function ‘lvzmq_ctx_create_reserve’: zmq_labview.c:223:27: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 223 | *pinstdata = bonzai_init(( void* )ninits ); | ^ zmq_labview.c: In function ‘lvzmq_send’: zmq_labview.c:485:25: warning: implicit declaration of function ‘zmq_msg_set_group’; did you mean ‘zmq_msg_set’? [-Wimplicit-function-declaration] 485 | if ( group && *group ) zmq_msg_set_group( &msg, group ); | ^~~~~~~~~~~~~~~~~ | zmq_msg_set zmq_labview.c: In function ‘lvzmq_receiver_thread’: zmq_labview.c:605:11: warning: variable ‘err’ set but not used [-Wunused-but-set-variable] 605 | int ret, err; | ^~~ zmq_labview.c: In function ‘lvzmq_join’: zmq_labview.c:860:8: warning: implicit declaration of function ‘zmq_join’; did you mean ‘lvzmq_join’? [-Wimplicit-function-declaration] 860 | ret = zmq_join( s->sock, group ); | ^~~~~~~~ | lvzmq_join zmq_labview.c: In function ‘lvzmq_leave’: zmq_labview.c:868:8: warning: implicit declaration of function ‘zmq_leave’; did you mean ‘lvzmq_leave’? [-Wimplicit-function-declaration] 868 | ret = zmq_leave( s->sock, group ); | ^~~~~~~~~ | lvzmq_leave so there are several warrnings, but the library is build and now I can test VIs which will use lvzmq64.so but first library call with finish with error 13. At this point, I tried to figure out how the Call Library Function is working and how to reproduce its task with c code, so I will get more info about the problem. The library is buit without .h file so in case of c call we need to use extern: #include <stdio.h> extern int lvzmq_ctx_create( int, int); //first function to call from labview to create context of zmq connection int main(){ printf("Test start\n"); int a; int b; lvzmq_ctx_create( a, b); return 0; } gcc compilation of this test gives an output: gcc test.c -L/home/user/Desktop/Lukas-Linux-folders/shared2/ -llvzmq64 /usr/bin/ld: /home/user/Desktop/Lukas-Linux-folders/shared2//liblvzmq64.so: undefined reference to `zmq_leave' /usr/bin/ld: /home/user/Desktop/Lukas-Linux-folders/shared2//liblvzmq64.so: undefined reference to `zmq_join' /usr/bin/ld: /home/user/Desktop/Lukas-Linux-folders/shared2//liblvzmq64.so: undefined reference to `zmq_msg_set_group' collect2: error: ld returned 1 exit status ok, so I got this error. It looks similar to warrnings reported by compiler when I build shared library. Now I stuck, because how it possible that those function calls are wrong, as its working on windows? Maybe the zmq package on Ubuntu doesn't contain those functions? Or I made a mistake when I build library. Any hint what to check next will be appreciated.
-
This is a nice improvement. Instead of configuring an additional c app in systemd file, its content can be run in the handler. The minimal wrapper code can be even more straightforward: void handler(int signum) { int fd; char * myfifo = "/tmp/LabVIEWCrossCommunication"; fd = open(myfifo,O_WRONLY); if(fd==-1) { printf("Error opening file: %s\n", strerror(errno)); } else { printf("Sending Close cmd to LabVIEWCrossCommunication \n"); write(fd, "Close", sizeof("Close")); close(fd); } unlink(myfifo); sleep(2); printf("Done\n"); } int main() { // printf("PID : %d\n", getpid()); //test with: kill -s SIGTERM pid signal(SIGTERM, handler); SharedLibEntryPoint(); return 0; } Thank you for your suggestion.
-
Thank you James, sending logs to Linux journal is easy thanks to pipes. Since I have not found any way to get any of Linux signal in my application I decided to open named pipe (Linux fifo) and read from it. Simple C application writes to the same pipe when service needs to be stopped. That makes possible to shutdown all LabVIEW modules correctly.
-
I'm trying to run LabVIEW application as a Linux service. To do that, I need to build the application without a user interface. Its possible and documented here: https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019RYlSAM&l=pl-PL However, if I will build an application which uses Python Nodes functions, it will crash with an unknown cpp error - so it's not supported or it's a LabVIEW bug. I can imagine that function is not supported - if by choosing "embedded version of the run-time engine" we are choosing to use the run-time engine which is used in Industrial Controller or cRIO . That makes sense because the feature of calling python code is not supported for targets like Industrial Controller. My question is what that feature do? What is the embedded version of the run-time engine (which target we can use)? crosspost : https://forums.ni.com/t5/Linux-Users/Embedded-version-of-run-time-engine-Python-Node/td-p/4240963
-
Hi, my challenge is to run our LabVIEW application as a Linux service. To achieve that, the systemd file needs to be created which defines execution files for starting and stopping the service. I have already look over the web to find some clues about this topic, however some knowledge is still missing and its related to how LabVIEW build shared library can interact with system. To explain it clearly I present what I have already done. Most services are running without a user interface, so the first task was to create a start execution file (Linux exe). I used this guide (https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019RYlSAM&l=pl-PL) to build our application as a shared library (so no user interface is used) and simple c program to launch it. It works, the application can be run from command line without UI. Similar command can be used in systemd file to define start of service ExecStart=/home/user/Desktop/MyAppNoUI-build/myappstart It also works. The service can be started and stopped. However, the stop function wasn’t defined so Linux sent KillSignal and the application was killed. I think it's not safe, I don't know what happened with all those open references etc. but I’m sure that I don't have any log from the application. So the first question is how to send the signal/message to the LabVIEW app? There is a possibility to specify the execution file which will be triggered on service stop, so this can be used. I have found - very simple - idea to trigger a c program which will create an empty file named “close” in the LabVIEW app directory. LabVIEW app checks periodically the directory and will trigger shutdown case when “close” would be found. This is a working solution, but I’m not sure if it's the best one. Next question is related to servicectl log access. It's very easy to use it in C (all printf functions are redirected to that log when the app is run as a service). However I don't know if it’s possible to do it with the LabVIEW app. I wonder if someone already done similar case so he can share ideas with us.