From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

#error "We don't know the Compiler" when compiling dll for use with LabVIEW

Solved!
Go to solution

Hi all,

 

this is not really a LabVIEW topic, but I didn't know where else to post, since it occurs when I try to compile a dll with the extcode.h file. I am trying to compile the following piece of Code.

 

#include "C:/Program Files/National Instruments/LabVIEW 2018/cintools/extcode.h"
void SendEvent(LVUserEventRef *whatever)
{
}

The compiler exits with the error: #error "We don't know the Compiler"

This, makes sense, because looking at platdefines.h, it is only expecting very few compilers. My compiler GCC 64-Bit is not part of that list.

Is there anything besides changing my compiler, that I could do about that?

Here's the part of platdefines.h that causes the error?

	#if defined(__MWERKS__)
		#define Compiler		kMetroWerks
	#elif defined(_MSC_VER) || defined(_NI_VC_)
		#define Compiler		kVisualC
	#elif defined(__SC__) || defined(_NI_SC_)
		#define Compiler		kSymanCWin
	#elif defined(__BORLANDC__) || defined(__BCPLUSPLUS__) || defined(_NI_BC_)
		#define Compiler		kBorlandC
	#else
		#error "We don't know the Compiler"
	#endif

 



Remember Cunningham's Law
0 Kudos
Message 1 of 7
(3,820 Views)

PeterFoerster,

It looks to me like it is the compiler that's causing the error, since it's not in the list of supported compilers. 

Also, you will probably have a little more success with C programming questions on the LabWindows/CVI forums, if you would like to repost this question there for more eyes on it.

C. Weeks
Product Support Engineer
NI
0 Kudos
Message 2 of 7
(3,776 Views)
Solution
Accepted by topic author PeterFoerster

The quick and dirty fix would be to define the necessary defines to try to get the header to work as if it was a different compiler. Since it is only for the LabVIEW header files which have not that many complicated dependencies on compiler and environment settings this might work.

A better way would be to edit the header files to make them recognize your compiler and environment. This is likely a bit more work to figure out right but will ultimately give you better control about making sure that all the necessary conditional compiles are set right.

All in all DLL programming with anything but Visual C will be always a tinker hell. If you got the compiler to finally work you still will have potential problems with the alignment settings to be right and other similar compiler intrinsicacies and once that works you'll end up with C runtime dependency issues, as your DLL will need a specific Gnu C runtime that was used by your compiler environment, that may or may not work on all Windows systems you want to deploy your software to.

 

These difficulties are not just caused by Microsoft, which of course doesn't make extra efforts to let other compilers work under Windows, but also by the Open Source community which doesn't feel comfortable with the closed source character of Windows too. In addition some people in Open Source have no problems at all to change things for the sake of change even if it means there will be incompatibilities between versions.

 

Not to forget license issues. Some license fanatics will claim that any software that contains something where Gnu is even just mentioned is illegal to be distributed as closed source app. Not a big problem if those fanatics don't work in your company but a pretty unbeatable obstacle if they happen to be working in your legal departement or closely related to it.

Rolf Kalbermatter
My Blog
Message 3 of 7
(3,771 Views)

Hi Rolf,

 

thanks for your thorough response, once again!

I actually had that same idea yesterday and just changed the platdefines.h file:

	#else
            #define Compiler kVisualC 
            #define ProcessorType kX64
	    //#error "We don't know the Compiler"

With that change I get past the error checking in that file. I get a warning, however, that there's a "corrupt .drectve at the end of def file". A quick search on stackoverflow told me that some file I linked is incompatible and when I call the function from LabVIEW, I get an error 1097, when calling PostLVUserEvent(). I can't extract any error information from the call, though.

 

Because of this, I am tempted to change my development environment and revert the changes to platdefines.h. It would seem that Code:Blocks + GCC 64 is not the right choice as soon as PostLVUserEvent() comes into this.

May I ask for your recommendation, for an IDE/compiler setup for this?

As mainly a LabVIEW developer I am not used to investing so much time in the compiler setup Smiley Wink



Remember Cunningham's Law
0 Kudos
Message 4 of 7
(3,753 Views)

@PeterFoerster wrote:

Hi Rolf,

 

thanks for your thorough response, once again!

I actually had that same idea yesterday and just changed the platdefines.h file:

	#else
            #define Compiler kVisualC 
            #define ProcessorType kX64
	    //#error "We don't know the Compiler"

With that change I get past the error checking in that file. I get a warning, however, that there's a "corrupt .drectve at the end of def file". A quick search on stackoverflow told me that some file I linked is incompatible and when I call the function from LabVIEW, I get an error 1097, when calling PostLVUserEvent(). I can't extract any error information from the call, though.

This proposed change would be very very bad.  You don't have Visual C so don't set the header defines to that. There is a reason that you have a compiler define in those headers that can be set for VisualC as the header file definitions then make some decisions that are specific to Visual C and that will of course fail for a Gnu C compiler like that. Also you should never just unconditionally use the else statement in such a decision tree for this but find out what your compiler sets as standard defines and use that to set your own defines.

 

Unfortunately while LabVIEW has a compiler define for the Gnu C Compiler it may still not be the right thing since most Gnu C compiler toolchains made to support Windows development don't use a stock Gnu C compiler but one with specific extensions to support Windows development more easily although that got less important in recent years as Gnu C supports now many Windows specific features although by far not everyone of them is working like in Visual C.

 

The corrupt drective at the end of def file is probably caused by the fact that your Code Blocks Gnu C compiler/linker doesn't really like the Microsoft Visual C generated object file format for labview(v).lib. That's another problem between Visual C and Gnu C compiling, the object file formats while using the same format in case of Windows development (COFF) aren't fully compatible for some reason. Supposedly this error shouldn't be a bad one but still it's frustrating.

 

The 1097 error while possibly caused  by such trouble is however more likely simply an error in your programming. The second parameter to PostLVUserEvent() must be a pointer to a data location that is 100% compatible with the native memory format for the LabVIEW data type of the event. 99% compatible doesn't cut it!!

 

Because of this, I am tempted to change my development environment and revert the changes to platdefines.h. It would seem that Code:Blocks + GCC 64 is not the right choice as soon as PostLVUserEvent() comes into this.

May I ask for your recommendation, for an IDE/compiler setup for this?

As mainly a LabVIEW developer I am not used to investing so much time in the compiler setup Smiley Wink


Well Visual C is your choice here. Everything else will cause similar problems that you only can solve if you have a deep understanding of C compilers and their complications.

 

The free Visual Studio community edition that you can download should be enough.

Rolf Kalbermatter
My Blog
Message 5 of 7
(3,737 Views)

Thanks!

 

I tried CVI, which uses the Windows SDK 8.1. I figured, if anyone should be compatible it's NI's own product. And development appeared much smoother, but the dll call from LabVIEW still failed with error 1097.

Of course, you were right about that again: I was using a char[], which needed to be changed to LStrHandle. Now I can send strings from my Dll to a LabVIEW event, how cool!

 

BTW, is there some hidden documentation I am missing about this topic? My only sources of information on the topic are:

This example, that I can't run.

This KB entry, that describes it very broadly.

And various topics on the forums by people having problems along the way.

Is there, for example, a list of datatypes the PostLVUserEvent() function can take? Its documentation page doesn't say much about that.

 

Either way, I now have a working minimal example that I can build on. I may have another question coming up, but I'll start a new topic for that and try a bit for myself first.

Thanks again for your help!



Remember Cunningham's Law
0 Kudos
Message 6 of 7
(3,725 Views)

@PeterFoerster wrote:

 


Is there, for example, a list of datatypes the PostLVUserEvent() function can take? Its documentation page doesn't say much about that.

 


Not specifically since it can take EVERY LabVIEW datatype that you can create inside LabVIEW. Basically it supports whatever complex datatype you can build in LabVIEW such as clusters of arrays of clusters containing clusters with arrays, strings, scalars and arrays again, etc..... So the full documentation of that would be an infinite amount of pages.

It's basically documented by the page in the installed LabVIEW documentation that describes how LabVIEW stores its various datatypes in memory.

Of course the datatype you pass in your C code needs to match exactly with the datatype that you used to generate the according user event refnum. There is no way for LabVIEW to verify this at runtime, it is your responsibility to make sure of that.

 

A handy trick is to simply wire the datatype you used to create the user event refnum to a Call Library Node parameter configured as Adapt to Type, then right click on that Call Library Node and select Create C code. This will generate a C file with an empty function implementation for the current Call Library Node configuration and all the necessary datatype declarations for the parameters. Copy and paste those datatype declarations into your C source file and you have the correct datatype to use to pass to PostLVUserEvent(). Of course you still will need to fill this with valid data by allocating all the handles correctly in your C code and fill in the rest but at least you have the correct datatype configuration.

 

And note that PostLVUserEvent() does not consume the data you pass to it but makes a deep copy of it into its own data to pass to the user event. So unless you store the handle(s) that you created somewhere, to reuse for subsequent calls in your routine you have to deallocate every single handle that you created appropriately after the call to PostLVUserEvent() in order to avoid memory leaks in your code.

 

Rolf Kalbermatter
My Blog
Message 7 of 7
(3,717 Views)