cancel
Showing results for 
Search instead for 
Did you mean: 

Cube32 feature request, need to handle CPP files.

Harvey White
Senior III

The support of CPP architectures in Cube32 is limited. While it would be nice if Cube32MX actually had CPP libraries, that's a long step.

It's very possible, however, to integrate a C++ layer on top of the existing code, where C++ routines call C routines.

However the process is limited by one feature in Cube32MX, and that is the dependence on main.c. How about a very small rewrite so that once there *is* a main.cpp, Cube32MX can make changes to it. Shouldn't be hard to do. Change main.c if it exists in the project, if it doesn't, then look for main.cpp and change it.

This will stop errors caused by forgetting to rename main.cpp back to main.c so that adjustments can be made, and then back from c to cpp.

19 REPLIES 19
Pavel A.
Evangelist III

The code generated by CubeMX and all the libraries are plain C.

IMHO renaming main.c to cpp will annoy many people who are comfortable with C.

An option in Eclipse project generation to add the "C++ nature" would be just enough.

Then users can add c++ files to the main C file, and bring their c++ libraries and stuff.

-- pa

Harvey White
Senior III

I agree with you, the libraries are plain C and can stay that way unless they get rewritten (and it's an option for STMicro).

There is already an option to add the C++ nature to a C project, it adds the C++ compiler and options, but does somewhat of a poor job in really configuring the environment for C++. That wasn't the idea. I already did that, and with a lot of tweaking here and there, it works, and works reliably. That's the C++ part of it.

However, the idea about renaming main.c to main.cpp works like this.

IF you have a main.c file, CubeMX does no renaming, and regenerates the file as needed. Thus, the C users will not be annoyed.

IF you have a main.cpp file, CubeMX does not rename it, that was for you to do once. CubeMX will regenerate the .cpp file as if it were renamed main.c

CubeMX already handles a renamed main.cpp (if it's in C) file without a problem. However, currently, you have to rename it yourself, then name it back again.

It's easy for C++ to call C files, I haven't found an easy way for C to call C++. Easy is defined as "it just does it without me having to do anything". Adding the C++ nature to the project is an easy one time step, and lasts even when the files are regenerated by CubeMX. So we're almost there.

What I would like is that CubeMX recognizes a .cpp file as valid, specifically main.cpp, and modifies it without having to rename it.

> libraries are plain C and can stay that way unless they get rewritten (and it's an option for STMicro)

They must be rewritten, but "C++ only" is definitely not an option. But anyway before going to higher layer code, ST must first learn basic C and make actually working, not bloated and flexible drivers in plain C. HAL is not even near to that!

Piranha
Chief II

> It's easy for C++ to call C files, I haven't found an easy way for C to call C++.

Internet is full of examples:

http://www.jonathanbeard.io/tutorials/Mixed_C_C++

https://stackoverflow.com/questions/2744181/how-to-call-c-function-from-c

https://isocpp.org/wiki/faq/mixing-c-and-cpp

In short - leave main.c as a C file and call C++ functions from there.

Harvey White
Senior III

Solved, but (and thanks Piranha) it took all three links to construct a workable solution, since each solution makes assumptions about the environment.

My exact solution is to do as little to main.c as possible (I've got an application structure defined in C++, and I want to be able to copy the user sections of main.c to another main.c without having to worry about the project name and type. To do this, I have a small function called cpp_link which calls the application init. The application init is in a different file, the cpp_link call from main remains constant for all projects. What cpp_link calls is constant, but the include file for cpp_link pointing to the application varies per application (if needed, keeping constant names over projects can be a help). This is a FreeRTOS environment, and the latest Atollic studio (V9.3.0).

This is using main.c as generated by CubeMX (and no, I don't want to work with the registers and LL drivers right now, did that on an Xmega, got the T shirt, T shirt's a rag).

the code for the body of cpp_link.cpp is:

#ifdef __cplusplus
	extern "C"
	{
#endif
	void cpp_link (void)
		{
			APPLICATION_init();
		}
#ifdef __cplusplus
	}
#endif

You not only need the extern "C" declaration, but it must have the #ifdef statements surrounding it. You get errors without the #ifdef statements.

The corresponding declaration in cpp_link.hpp is

#ifdef __cplusplus
	extern "C"
	{
#endif
	void cpp_link (void);
#ifdef __cplusplus
	}
#endif

Again, note the syntax and the inclusion of the #ifdef statements

In the main program do the following: What you have here is your own task that takes the place of the main task loop. That task loop is all C++, as is cpp_link and the application_init code. The intention is that you start up your main task for the application, and do not use the main program loop. This allows you to adjust the task size independent of the CubeMX settings for FreeRTOS. Note that the main task loop in main.c ticks over very slowly.

So the last code that you need is in main.c.

  /* USER CODE BEGIN 5 */
  /* Infinite loop */
	  cpp_link();
	  // cpp_link goes to application init
	  // main task does nothing
  for(;;)
  {
    osDelay(10000);
  }
  /* USER CODE END 5 */ 

This partitions your application loop and keeps it away from main.c, giving you a minimum amount of things you have to do to main.c to get it to work. You can likely just copy main.c from project to project, regenerate it with CubeMX, keeping all the settings you need, and not worry about the project or the rest of the setting, since they're all in your C++ code.

I would *still* like to see CubeMX deal gracefully with a C++ main file, though.

> This partitions your application loop and keeps it away from main.c, giving you a minimum amount of things you have to do to main.c to get it to work.

Yes, exactly this.

> I would *still* like to see CubeMX deal gracefully with a C++ main file, though.

IMHO here is how this can be done in the way acceptable for conservative users like myself:

If instead of main.c there is main.cpp (assume the user renamed it) - just keep treating is as plain C.

Let the smart user manage all these extern "C", #ifdef cplusplus and so on in user code sections.

-- pa

Harvey White
Senior III

We agree completely. Now all we need to do is to wait until ST Micro twigs this as a solution (trans: sees that this works, decides to do it, and so on) and then the problem is solved.

In the meantime, my particular solution for my architecture hasn't broken yet, and seems to be a reliable solution. NOT (I think) that we OUGHT to have to do this, or find a workaround. It is, however, what we have to deal with.

Still, let's hope that people in similar situations find this situation reasonable.

As a note: I would have been more or less (less because of program structure) happy to allow and use only C. However, the program is complex enough (a rather involved graphics application) that the C++ class would have been very helpful (graphics_object -> point -> line -> panel -> button with various divergences from the path.) If this isn't what you do (and not likely) then you may want to look at the architecture to see *if* C++ and class inheritance could help.

saying that, though, there are problems and system architectures where C++ makes life a lot easier. It also complicates some things as well.

The utility of C++ for a project depends on the architecture, the size and the point at which you decide that there *ought* to be an easier way to do this.

Where the program was for me, was at the point wher I decided that there had to be an easier way, that a redesign was needed, and that (for me) the redesign worked.

And no, you won't learn this from very many places, practice and experience seem to be a good thing.

I also wouldn't (personal opinion) say that "I don't need C++, C is good enough).

I did the same thing with assembly, then C, and now C++ as the project evolved...

Each upgrade (rewrite with a different language) brings advantages and disadvantages. It's up to you to figure out what to use and where (if anywhere) to stop.

Although this thread is some years old, I'd like to reactivate it.

In my special case, I'd like to call touchgfx::OSWrappers::signalvSync() from a c file.

I used your cpp_link frame listed above to make the c++ function available in c - which kinda works. I just get anerror at compiling for "unknown type name 'namespace'" at the line where the touchgfx namespace is generated.

Any suggestions on how to fix that?

Thanks in advance!

What it seems like is that the C compiler is trying to compile the C++ part of the code. I've had to remove the references in the search path for the C compiler so that only the C++ compiler can find it.

I've not had good results with touchGFX in a C++ environment, and went back to using my own graphics routines. I found that the programs wouldn't compile at all using CubeIDE, and had to be compiled with the TouchGFX tools. So everything was handled with the TouchGFX builder. That may have been fixed, though. I personally found TouchGFX to be limited, myself.

Hope this might work