bublina Posted March 2, 2013 Report Share Posted March 2, 2013 Hello, I am wrapping ffmpeg into LabView, so far I wrapped few functions to set up a stupid videoplayer, all works, but only in debug mode. once I want to use release build, during setting up the functions in library call dialog, I get error saying : "Entrypoint of procedure imaqCloseToolWindow could not be located in avcodec-54.dll" or such, I translated from windows native language. From the error description, it semmed to me a linker problem, but code compiles and linkes without errors. All DLLs are in place. So far, I did not find the build option, that might be causing this. Please help me, why is this happening. I know it is definitely some stupid nwbie mistake. I stripped down the code for release build to only contain returns and such. And still getting this error. This is how does the *.h file looks like: //Header for FFMPEG LV wrapper#define DLL_EXPORT __declspec(dllexport)#ifdef __cplusplus extern "C" {#endif#include "libavcodecavcodec.h"#include "libavformatavformat.h"#include "libswscaleswscale.h"#include "libavutilavutil.h"#include "nivision.h"#include <string.h>#pragma comment(lib, "devlibavcodec.lib")#pragma comment(lib, "devlibavformat.lib")#pragma comment(lib, "devlibswscale.lib")#pragma comment(lib, "devlibavutil.lib")#pragma comment(lib, "nivision.lib")#pragma pack(push, 1)typedef struct FFMPEG_Video{ AVFormatContext *pFormatCtx; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pDecFrame; AVFrame *pBGRAFrame; SwsContext *pConvertCtx; int VideoStream; int AudioStream;} pFFMPEG_Video;#pragma pack(pop)#pragma pack(push, 1)typedef struct{ char *name; Image *address;} IMAQ_Image;#pragma pack(pop)DLL_EXPORT int32_t FFMPEG_open_file(int32_t *session, char *path);DLL_EXPORT int32_t FFMPEG_read_frame(int32_t *session, IMAQ_Image *LVFrame);DLL_EXPORT int32_t FFMPEG_close_file(int32_t *session);DLL_EXPORT void FFMPEG_register_all(void);#ifdef __cplusplus }#endif The code compiles and links without warnings (W4) Please help Best regards Quote Link to comment
bublina Posted March 2, 2013 Author Report Share Posted March 2, 2013 (edited) So problem causing is here: Project properities->Linker->Optimization->References if optimized = error, if not, all is ok. Some clarification would be nice, I only found it trial @ error. Edited March 2, 2013 by bublina Quote Link to comment
candidus Posted March 11, 2013 Report Share Posted March 11, 2013 The only reason I could think of is that optimization removes entry points of which the optimizer thinks they aren't used... Do you call imaqCloseToolWindow() somewhere in your code? Quote Link to comment
Rolf Kalbermatter Posted March 12, 2013 Report Share Posted March 12, 2013 So problem causing is here: Project properities->Linker->Optimization->References if optimized = error, if not, all is ok. Some clarification would be nice, I only found it trial @ error. Well imagCloseToolWindow() definitely is an IMAQ (Ni Vision) function and as such never could be located in the avcodec.dll. Seems like the linker is messing up the import tables somehow when told to optimize the import and/or export tables. Could be because of some wizardy in the NI Vision DLL but certainly seems a bug of the link stage optimizer in the compiler. Is this Visual C or LabWindows CVI? Quote Link to comment
ThomasGutzler Posted March 25, 2014 Report Share Posted March 25, 2014 (edited) Hi, I realise this hasn't been touched for a year, but there is always hope... As explained here I'm trying to read quicktime videos frame by frame. I'd like to do this using the ffmpeg library but I got stuck way earlier than bublina. Possibly because I've never interfaced to external code from LabVIEW before... So I got myself a copy of the ffmpeg-shared and -dev package and tried out the Shared Library Import on libavformat.dll. After adding the Include folder from my visual studio installation I got 73 out of 162 functions recognised. It turns out those are the ones that don't have a struct as a parameter. First one to fail was this: int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags); The following symbols are not defined: AVStream; The AVStream struct is defined in avformat.h, which I specified as header for the library. Surely it got parsed. So why isn't this working? Isn't the import wizzard clever enough to parse structs or is there a trick I'm unaware of? I read in another post by rolfk that, if I was using the call library node, I can just define separate inputs for each of the elements of a struct (instead of passing a bundled cluster to the library). Before doing that (and defining all the other 1000000 structs this one depends on) I'd like to be sure there isn't an easier way. Cheers, Tom Edit: Just noticed that not all functions with structs as parameters failed to import. There is this one: which was created with an empty cluster s. AVFormatContext is also defined in avformat.h. As a bonus, I also found three "Custom Controls" in my imported library. One of them is called AVInputFormat and has 4 elements - unlike the actual definition in the header file, which has many more. But importantly, the first four are standard types like char and int while the 5th one is a struct. So it seems, the parser wasn't clever enough to resolve a struct inside a struct. Maybe I was a bit too ambitious with this project; it looks like this isn't going to be just a one weekend thing. Edited March 25, 2014 by ThomasGutzler Quote Link to comment
Rolf Kalbermatter Posted March 25, 2014 Report Share Posted March 25, 2014 Hi, I realise this hasn't been touched for a year, but there is always hope... As explained here I'm trying to read quicktime videos frame by frame. I'd like to do this using the ffmpeg library but I got stuck way earlier than bublina. Possibly because I've never interfaced to external code from LabVIEW before... So I got myself a copy of the ffmpeg-shared and -dev package and tried out the Shared Library Import on libavformat.dll. After adding the Include folder from my visual studio installation I got 73 out of 162 functions recognised. It turns out those are the ones that don't have a struct as a parameter. First one to fail was this: int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags); The following symbols are not defined: AVStream; The AVStream struct is defined in avformat.h, which I specified as header for the library. Surely it got parsed. So why isn't this working? Isn't the import wizzard clever enough to parse structs or is there a trick I'm unaware of? I read in another post by rolfk that, if I was using the call library node, I can just define separate inputs for each of the elements of a struct (instead of passing a bundled cluster to the library). Before doing that (and defining all the other 1000000 structs this one depends on) I'd like to be sure there isn't an easier way. Cheers, Tom Edit: Just noticed that not all functions with structs as parameters failed to import. There is this one: snip.png which was created with an empty cluster s. AVFormatContext is also defined in avformat.h. As a bonus, I also found three "Custom Controls" in my imported library. One of them is called AVInputFormat and has 4 elements - unlike the actual definition in the header file, which has many more. But importantly, the first four are standard types like char and int while the 5th one is a struct. So it seems, the parser wasn't clever enough to resolve a struct inside a struct. Maybe I was a bit too ambitious with this project; it looks like this isn't going to be just a one weekend thing. Well let me tell you about the lvZIP library on OpenG. That is magnitudes simpler than the FFMPEG library in terms of number of exported APIs as well as functionality. And creating that was more like a one or two year parttime project than a weekend project . And I knew some substantial C programming when I started with that, although I sure learned a few tricks during development of that library too. So even with an optimistic outlook I would consider the FFMPEG library to be a substantial full time project that likely takes up several months to do right. As to your specific problem: those AVStream and other parameters are so called opaque data types. Basically that means that the external declaration is simply a named datatype with no public data content. As such LabVIEW can not do anything with this datatype and the import wizard has to leave the not fully declared datatype undefined. Even if you go into the header file and add something to the structure to make it parsable you are really misguiding the import wizard as to what it should do. The only kind of fix that might sort of work would be to define the AVStream and others to be of type void instead of an unfinished struct. Then AVStream* will get void* which is actually what you want to have here. The idea about opaque types is that they are in the external API only treated as a pointer to an undefined struct. Much like what Windows uses HANDLEs for. They are basically a pointer to a data structure that the actual API knows how to interpret, but the caller never should be concerned about in any way. By making it an opaque type the programmer can make sure that any caller will never be able to concern itself with the contents of that structure. Internally in the library source code there is another header which declares the datatype completely so it can be used inside the library properly. The advantage of using AVStream* and friends as seen here instead of declaring every of these types as void* instead, is that you as caller can then not accidentally pass a pointer that describes a different resource than an FFMPEG stream to this function. Well that applies for C(++) only of course. In LabVIEW you don't have that automatic syntax check based on the C header declaration. Personally I would probably redefine all those opaque types to void and then let the import wizard correctly create the library calls. Here they should then end up as a pointer sized integer. You end up with the problem that you loose every type safety as a pointer sized integer that points to an AVStream is not distinguishable from another pointer sized integer that points to some other resource. But solving that issue is even more involved and definitely will go way beyond any type of weekend project. 1 Quote Link to comment
ned Posted March 25, 2014 Report Share Posted March 25, 2014 The AVStream struct is defined in avformat.h, which I specified as header for the library. Surely it got parsed. So why isn't this working? Isn't the import wizzard clever enough to parse structs or is there a trick I'm unaware of? I read in another post by rolfk that, if I was using the call library node, I can just define separate inputs for each of the elements of a struct (instead of passing a bundled cluster to the library). Before doing that (and defining all the other 1000000 structs this one depends on) I'd like to be sure there isn't an easier way. Not quite right! What you saw was a post from Rolf that said that if the struct is passed by value, then you should pass each struct member as a separate parameter. However, if you are passing the struct by reference, which is the much more common case (and the case in your function prototype), then you need to pass a single parameter representing a pointer to sufficient memory to contain the struct. Often the easiest way to do this is by defining a cluster that matches the struct definition, but you can also pass a preallocated array or string of the correct length. Passing individual struct elements will definitely not work if the function expects the struct to be passed by pointer. Quote Link to comment
Rolf Kalbermatter Posted March 25, 2014 Report Share Posted March 25, 2014 Not quite right! What you saw was a post from Rolf that said that if the struct is passed by value, then you should pass each struct member as a separate parameter. However, if you are passing the struct by reference, which is the much more common case (and the case in your function prototype), then you need to pass a single parameter representing a pointer to sufficient memory to contain the struct. Often the easiest way to do this is by defining a cluster that matches the struct definition, but you can also pass a preallocated array or string of the correct length. Passing individual struct elements will definitely not work if the function expects the struct to be passed by pointer. You are fully right with all of this, except that for opaque data pointers the caller doesn't and shouldn't even have any idea about the size of the structure the pointer is pointing too. Instead such APIs always have a function that will create the according structure and then hand back the data pointer to the caller, and logically an according function that will take that pointer and deallocate any possible resources it refers to including the actual structure itself. For LabVIEW it is in all cases just a pointer sized integer. Quote Link to comment
ThomasGutzler Posted March 31, 2014 Report Share Posted March 31, 2014 I think this turned into a self education project more than anything else. Instead of building a library that fully wraps ffmpeg, I went on their forum and wondered if I could implement the "Simplest ffmpeg player". It turns out, I couldn't (yet) - got stuck in line 3. A few problems: I'm getting an error on the av_find_stream_info() node I had to define the AVFormatContext struct as a cluster because I need to use some of its properties later on. I wasn't sure if I had done that rightAll pointers were represented by an I64 How do you do "char filname[1024]"? Only thing I could think of is a cluster that contains 1024 U8 controls Looking at the filename I've reconstructed from the U8 array I found that its first 24 characters were missing. To me, that was a success, because it means I got *something* right and 24 got me thinking... There were 6 pointers defined in the cluster before filename, if I change the pointer size from I64 to I32 I can make it work so that the entire filename is reconstructed correctly. And 4 byte sized pointers doesn't seem unreasonable seeing the library is compiled for 32bit. That probably means that all other pointers in the cluster should be 4 bytes long too. But what about the pointer I pass into MoveBlock? If I change that to I32, the filename contains mostly unreadable characters. Where do I draw the line? Surely I can't just type cast the pointer and hope all is well? Tom I've attached my project, which needs the shared lib from here player.zip Quote Link to comment
Rolf Kalbermatter Posted March 31, 2014 Report Share Posted March 31, 2014 I think this turned into a self education project more than anything else. Instead of building a library that fully wraps ffmpeg, I went on their forum and wondered if I could implement the "Simplest ffmpeg player". It turns out, I couldn't (yet) - got stuck in line 3. A few problems: I'm getting an error on the av_find_stream_info() node I had to define the AVFormatContext struct as a cluster because I need to use some of its properties later on. I wasn't sure if I had done that rightAll pointers were represented by an I64 How do you do "char filname[1024]"? Only thing I could think of is a cluster that contains 1024 U8 controls [*] Looking at the filename I've reconstructed from the U8 array I found that its first 24 characters were missing. To me, that was a success, because it means I got *something* right and 24 got me thinking... There were 6 pointers defined in the cluster before filename, if I change the pointer size from I64 to I32 I can make it work so that the entire filename is reconstructed correctly. And 4 byte sized pointers doesn't seem unreasonable seeing the library is compiled for 32bit. That probably means that all other pointers in the cluster should be 4 bytes long too. But what about the pointer I pass into MoveBlock? If I change that to I32, the filename contains mostly unreadable characters. Where do I draw the line? Surely I can't just type cast the pointer and hope all is well? Tom I've attached my project, which needs the shared lib from here player.zip You can't use fixed size pointer elements if you ever intend to allow your VIs to run both in LabVIEW 64 Bit and LabVIEW 32 Bit. A pointer is 32 bit when the library is compiled for 32 Bit and 64 Bit when the library is compiled for 64 Bit. The library must be compiled in whatever bitness the calling process is, e.g. 32 Bit for LabVIEW 32 Bit or 64 Bit for LabVIEW 64 Bit, independent of the OS bitness you are running on. One the other hand you do not have 32 bit and 64 bit pointers intermixed in the same process environment. It is either or, never both at the same time. Having to redefine AVFormatContext struct in your own code is definitely a very bad sign. If they are not declared as a complete type in the public headers of FFMPEG then they are not meant to be accessed from outside the library! No exceptions here! The reason being that such types typically will change between different versions of the library and accessing those structs directly will mean that your calling application is not anymore able to deal with a different version of the library. Quote Link to comment
ned Posted March 31, 2014 Report Share Posted March 31, 2014 How do you do "char filname[1024]"? Only thing I could think of is a cluster that contains 1024 U8 controls Yes, that's the right way to do it, ugly as it may look. I can't open your code (still on LabVIEW 2012 here) so I can't see exactly how you're using it, but using "Array to Cluster" with the size set to 1024 is an easy way to generate such a cluster. If you're passing filename as a separate parameter rather than an element of a struct, then you can use initialize array to generate an array of 1024 U8 instead. Quote Link to comment
ThomasGutzler Posted April 1, 2014 Report Share Posted April 1, 2014 One the other hand you do not have 32 bit and 64 bit pointers intermixed in the same process environment. It is either or, never both at the same time. So why does my 32 bit LabVIEW use I64 when I tell it to make a pointer-sized integer parameter on a cln? Having to redefine AVFormatContext struct in your own code is definitely a very bad sign. If they are not declared as a complete type in the public headers of FFMPEG then they are not meant to be accessed from outside the library! No exceptions here! The reason being that such types typically will change between different versions of the library and accessing those structs directly will mean that your calling application is not anymore able to deal with a different version of the library. Maybe redefine isn't the right word. The AVFormatContext struct is fully declared in the header - just couldn't be imported by the library import, so I defined it from scratch. It seemed to be the easier way at the time and helped me understand things (better). Maybe I'm missing a few preprocessor definitions for a more successful import. The struct is definitely supposed to be used in applications. This seems to be a way to find your first video stream in the list of available streams: AVFormatContext *pFormatCtx;pFormatCtx = avformat_alloc_context();avformat_open_input(&pFormatCtx,filepath,NULL,NULL);for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { // congratulations, you found the video stream ned, I can save you a 2012 version if you want. The "problem" with the filename isn't that I'm passing it but that it's part of that struct which is returned to me. Tom Quote Link to comment
Rolf Kalbermatter Posted April 1, 2014 Report Share Posted April 1, 2014 So why does my 32 bit LabVIEW use I64 when I tell it to make a pointer-sized integer parameter on a cln? LabVIEW uses on diagram level always 64 bit integers for pointer sized values, since LabVIEW also mandates that the flattened format of every datatype is always the same on any LabVIEW platform. If it would adapt the pointer typed integer to the platform, a cluster containing one or more pointers would be variable sized depending on the plattform you run it on. This has one bad implication: You can in LabVIEW not define a cluster that contains pointers and pass it to a Call Library Node as struct. Such a struct will always mismatch the natively expected datatype either on the 32 bit or 64 bit system. The only solution there is to create both types and call the function with conditional compiling dependent on the platform it is executing on. It is unfortunate but the LabVIEW developers had the choice to maintain the long standing (since LabVIEW 2.5) paradigma of guaranteeing flatten data format consistency across all LabVIEW platforms or allow easy interfacing to external libraries containing pointers in their struct parameters. Considering that the flatten data paradigma exists already over 20 years, and pointers are not really a native feature of LabVIEW anyways, it is easy to see why they did the choice they did. While accessing the interna of AVFormatContext seems indeed required, it is simply a total pain in the ass to do such things in a LabVIEW diagram, especially when you consider the magic you need to do when such structures contain pointers, which they most likely do, and you wanting to support 32 bit and 64 bit seamlessly. This is definitely the point where starting to write a LabVIEW specific wrapper library in C(++) is simply the only useful way to proceed. Quote Link to comment
ned Posted April 1, 2014 Report Share Posted April 1, 2014 ned, I can save you a 2012 version if you want. The "problem" with the filename isn't that I'm passing it but that it's part of that struct which is returned to me. If you post a 2012 version of your code, I'll take a look and see if I can suggest an alternate approach. If for some reason it's easier - and it might be in this case - you can pass a preallocated array, as large as the struct, in place of a cluster, then parse out sections of that array when it's returned to you. Quote Link to comment
ThomasGutzler Posted April 2, 2014 Report Share Posted April 2, 2014 ned, Thanks for your offer, but at this point it might be better to leave it where it is and never touch it again Rolf, Thanks for your careful explanations, they are very helpful and most appreciated. For what it's worth, I agree with the LabVIEW developers for keeping the size of pointers constant over platforms. While accessing the interna of AVFormatContext seems indeed required, it is simply a total pain in the ass to do such things in a LabVIEW diagram, especially when you consider the magic you need to do when such structures contain pointers, which they most likely do, and you wanting to support 32 bit and 64 bit seamlessly. This is definitely the point where starting to write a LabVIEW specific wrapper library in C(++) is simply the only useful way to proceed. I was wondering how long it would take for that suggestion to come up. I shall accept the challenge - again, more for self-educational purpose more than anything else. That's what "weekend projects" are for, right? Any reading suggestions are welcome. This is what I've bookmarked so far: Building a DLL in Visual C++ Writing Win32 Dynamic Link Libraries (DLLs) and Calling Them from LabVIEW Building a Shared Library to call from LabVIEW So yes, there won't be an ffmpeg.lvlib coming from my end for a while Cheers Quote Link to comment
ShaunR Posted April 2, 2014 Report Share Posted April 2, 2014 Rolf, Thanks for your careful explanations, they are very helpful and most appreciated. For what it's worth, I agree with the LabVIEW developers for keeping the size of pointers constant over platforms. I was wondering how long it would take for that suggestion to come up. This is one of the few points where I disagree with Rolf. Maintaining a wrapper seems like a good idea to start with, but you end up replicating all the functions of the original in the wrapper or reducing the function-set available to LabVIEW. LabVIEW is cross platform already and although it takes a bit more up-front, it is much easier to encapsulate the original, extend and maintain. Once you have good LabVIEW coverage, you can just replace the DLLs . This is great if they are 3rd party supplied (and run the LabVIEW test harnesses). It also means that end-users can update them without you having to do anything. If they add a function, you only need to create the LabVIEW part and it's job-done. There are a few projects that suddenly became unusable because they stopped maintaining the wrapper (not Rolf, of course, he maintains them forever ). Have I ever said how much I hate OpenSSL? (just a short gripe because it's doing my head in for similar reasons ) Quote Link to comment
Rolf Kalbermatter Posted April 2, 2014 Report Share Posted April 2, 2014 This is one of the few points where I disagree with Rolf. Maintaining a wrapper seems like a good idea to start with, but you end up replicating all the functions of the original in the wrapper or reducing the function-set available to LabVIEW. LabVIEW is cross platform already and although it takes a bit more up-front, it is much easier to encapsulate the original, extend and maintain. Once you have good LabVIEW coverage, you can just replace the DLLs . This is great if they are 3rd party supplied (and run the LabVIEW test harnesses). It also means that end-users can update them without you having to do anything. If they add a function, you only need to create the LabVIEW part and it's job-done. There are a few projects that suddenly became unusable because they stopped maintaining the wrapper (not Rolf, of course, he maintains them forever ).Have I ever said how much I hate OpenSSL? (just a short gripe because it's doing my head in for similar reasons ) We agree to disagree here! I find maintaining platform discrepancies and low level pointer acrobatics on LabVIEW diagram level simply a pain in the a$$ and a few other places too at the same time. It's much easier to maintain these things on C source level and allows easy adaption in a generic way so that the LabVIEW part can concentrate on doing what it is best in and the C part too. I know that the lvZIP is not an ideal example since the 64 bit support is still not released but basically supporting 64 bit there if everything had been done on LabVIEW level itself would be a complete nightmare, now it is basically working out one kink in the cable to allow private refnums to work for 64 bit pointers too. There are two solutions for that, using an undocumented LabVIEW feature that exists since at least LabVIEW 7.0 or cooking up something myself to translate between 64 bit pointers and LabVIEW 32 bit refnums. The real reason that lvZIP still isn't 64 bit however are much more profane aside from time constraints. For one I only recently got a computer with 64bit OS and for the other a change from sourceforge about maintenance of the SVN read/write access which is not natively supported by TortoiseSVN has kept me from working on this for a long time. But an API like OpenSSL or FFMPEG which makes use of complex parameters beyond flat clusters is IMHO simply not maintainable for the long term without C wrappers. Quote Link to comment
ThomasGutzler Posted April 2, 2014 Report Share Posted April 2, 2014 Aha, I'm in a very good position here. I never really intended to turn this into a publicly available/supported project. I just wanted to be able to read the video from .mov files for a private side project. QTlib does that for me, just takes a bit longer. I can just try out both alternatives and see which I like better. It might take a bit longer to get two wrappers working to the point where I can decode the video stream; or I might give up on one half way through. It doesn't matter if it doesn't work out. The main point for me at the moment is that I'm learning new stuff. And if I like it so much that I can't stop and it's starting to become useful for others I will turn it into a public project. Next item on my reading list: anything I can find about cintools starting here. Quote Link to comment
Rolf Kalbermatter Posted April 2, 2014 Report Share Posted April 2, 2014 Aha, I'm in a very good position here. I never really intended to turn this into a publicly available/supported project. I just wanted to be able to read the video from .mov files for a private side project. QTlib does that for me, just takes a bit longer. I can just try out both alternatives and see which I like better. It might take a bit longer to get two wrappers working to the point where I can decode the video stream; or I might give up on one half way through. It doesn't matter if it doesn't work out. The main point for me at the moment is that I'm learning new stuff. And if I like it so much that I can't stop and it's starting to become useful for others I will turn it into a public project. Next item on my reading list: anything I can find about cintools starting here. You don't use Cins anymore and consequently also not cintools. The only things in that directory that are still needed are the extcode.h file (and it's support headers but you usually don't deal with them directly) and the labview.lib file to link to your shared library. Cins aren't even supported on newer LabVIEW platforms such as the 64 bit versions or Linux RT. Shared Library/DLL with the Call Library Node is the way to go for several years already. If you do it right you end up with one VI library without any platform specific code paths and one shared library per supported platform and one C source code for your shared library/wrapper. Quote Link to comment
ShaunR Posted April 2, 2014 Report Share Posted April 2, 2014 (edited) Next item on my reading list: anything I can find about cintools starting here. Ah. Here Rolf and I are in total agreement.. CINS are to CLFNs as MP3s are to gramophone records. We agree to disagree here! I find maintaining platform discrepancies and low level pointer acrobatics on LabVIEW diagram level simply a pain in the a$$ and a few other places too at the same time. It's much easier to maintain these things on C source level and allows easy adaption in a generic way so that the LabVIEW part can concentrate on doing what it is best in and the C part too. I know that the lvZIP is not an ideal example since the 64 bit support is still not released but basically supporting 64 bit there if everything had been done on LabVIEW level itself would be a complete nightmare, now it is basically working out one kink in the cable to allow private refnums to work for 64 bit pointers too. There are two solutions for that, using an undocumented LabVIEW feature that exists since at least LabVIEW 7.0 or cooking up something myself to translate between 64 bit pointers and LabVIEW 32 bit refnums. The real reason that lvZIP still isn't 64 bit however are much more profane aside from time constraints. For one I only recently got a computer with 64bit OS and for the other a change from sourceforge about maintenance of the SVN read/write access which is not natively supported by TortoiseSVN has kept me from working on this for a long time. I know we do And my view that Linux is a community version of Windows 95 (a GUI bolted onto a CMD prompt), probably won't sit well either . I wasn't actually referring to lvZIP. I was thinking more about SQLite - but as you bring it up; it kind of proves my point.Zlib supports 64 bit so the only reason 64 bit isn't supported in the openG tools is the wrapper.In fact. Transport.lvlib supports it. People could have just replaced the DLL if it wasn't for the wrapper From the Zlib website: Will zlib work on a 64-bit machine?Yes. It has been tested on 64-bit machines, and has no dependence on any data types being limited to 32-bits in length. I think I even gave you a 64 bit version of zlib at one point (with minizip) But an API like OpenSSL or FFMPEG which makes use of complex parameters beyond flat clusters is IMHO simply not maintainable for the long term without C wrappers. I'm about you make you eat those words Slightly off topic. But does VxWorks come with libssl? Edited April 2, 2014 by ShaunR Quote Link to comment
Rolf Kalbermatter Posted April 2, 2014 Report Share Posted April 2, 2014 Ah. Here Rolf and I are in total agreement.. CINS are to CLFNs as MP3s are to gramophone records. With such comparisons you should watch out for the order of the comparands. The way you wrote it I would definitely not agree with. I know we do And my view that Linux is a community version of Windows 95 (a GUI bolted onto a CMD prompt), probably won't sit well either . I'm not a Linux fan, but that comparison is certainly not very fair. Linux had full featured OS support at a time when Windows still was mostly a crashy UI shell on top of an antique floppy disk manager. I wasn't actually referring to lvZIP. I was thinking more about SQLite - but as you bring it up; it kind of proves my point.Zlib supports 64 bit so the only reason 64 bit isn't supported in the openG tools is the wrapper.In fact. Transport.lvlib supports it. People could have just replaced the DLL if it wasn't for the wrapper From the Zlib website: I think I even gave you a 64 bit version of zlib at one point (with minizip) ZLIB is not the problem. But lvZIP also incorporates the minizip extra code to support the ZIP format. ZLIB "only" implements the deflate and inflate algorithme which is used to compress/decompress the actual streams in a ZIP file. ZIP adds an archive management around that. With ZLIB alone you can not create archives, only compressed files. This ZIP code was necessary anyhow, implementing the ZIP code in LabVIEW definitely is an exercise that I would never even have started with. So I had the choice to use ZLIB as standard library, which was in a transition phase at that moment (changing calling conventions on Windows to make it more consistent) and have my own ZIP code wrapper taken from minizip (minizip is an executable not a shared library), or put it all in one shared library for ease of distribution. Since there was already a custom shared library component anyhow the choice was easy. Also the problem about 32 bit and 64 bit transition would have remained. The Call Library Interface does not support seamless change between those two environments if you have any structure parameter containing non flat data. Even opaque pointers are sort of problematic as you end up to either use the pointer sized integer and having to route it as 64 bit integer throughout the diagram, loosing any possibility to prevent a programmer to mis-wire these "pointers" with just about any other numeric in a diagram, or create a C wrapper anyhow at this point. The trick with the LabVIEW datalog refnum doesn't work reliable here since they are only 32 bit on either platform. Another issue I have been trying to work on is that minizip does absolutely nothing to deal with character code pages. As a DOS command line tool that is not so bad since it inherits the ACP_OEM codepage for your country setting and ZIP files are supposed to be ACP_OEM encoded. The same code called from LabVIEW or any other GUI app will use the ACP_ANSI codepage which is also depending on your country setting, containing usually mostly the same extra characters but of course at totally different indexes in the upper 128 codes. Doing this translation on Windows is a call to two WinAPIs to translate between ANSI to UTF16 and then OEM and vice versa. Doing it on Mac are a few more and completely different APIs to translate over the widechar roundabout and that only guarantees that the result is similar to Windows and doing it under any Linux version is simply a total pain in the a$$ since there are about 5 different libraries to do character encoding translation but all come with their own list of secondary dependencies. Doing that all in the C code wrapper is bad enough, but doing it in the LabVIEW diagram is simply an exercise in vain. Slightly off topic. But does VxWorks come with libssl? vxWorks doesn't come with openSSL out of the box but several NI tools such as the webserver will install an openSSL library (that NI supposedly cross compiled for this purpose). The one problem with this is that you have no real control about which OpenSSL version gets installed, which can be a serious problem when you want to use certain features. Just about every OpenSSL client sooner or later tends to check for the OpenSSL version to disable some functionality based on lack of feature support, or to do rather complicated circumventions to work around specific bugs in certain versions. A nice exercise to add to a LabVIEW wrapper too! Quote Link to comment
ShaunR Posted April 2, 2014 Report Share Posted April 2, 2014 vxWorks doesn't come with openSSL out of the box but several NI tools such as the webserver will install an openSSL library (that NI supposedly cross compiled for this purpose). Sweet.I'll test it out on a sbRIO at the weekend once I can remember where I "stored" it Quote Link to comment
Rolf Kalbermatter Posted April 2, 2014 Report Share Posted April 2, 2014 Sweet.I'll test it out on a sbRIO at the weekend once I can remember where I "stored" it I'm afraid I was seeing ghosts. I remember having seen some OpenSSL libraries in the past on a cRIO but currently can't come up with any in the one I have nor in the RT Image files that are used to deploy components to a RT system. Found it! It's the nissl component. And the libraries are renamed nilibeay32 and nissleay32. And it seems 0.9.8i. Not really very new. 1 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.