combining XC and C++
-
- Experienced Member
- Posts: 75
- Joined: Thu Feb 02, 2012 3:32 pm
combining XC and C++
the problem i'm having is that when i call a function from XC, it follows the the includes thus trying to parse all of my code, most of which is quite heavy in C++. the C++ capabilities in XC highly limiting and thus it is unusable for my purposes.
is there a way to do use something like extern in XC and then define it with C?
alternatively, is there a way to use straight C/C++ and still do stuff like threading and channel/port io?
i know it's possible to make functions that use inline assembly to do the dirty work but i was hoping this had already been done as the asm resource system is alien to me.
please help. :(
is there a way to do use something like extern in XC and then define it with C?
alternatively, is there a way to use straight C/C++ and still do stuff like threading and channel/port io?
i know it's possible to make functions that use inline assembly to do the dirty work but i was hoping this had already been done as the asm resource system is alien to me.
please help. :(
-
- Experienced Member
- Posts: 75
- Joined: Thu Feb 02, 2012 3:32 pm
i figured it out. :D
here's how you do it:
in your .xc file declare the function you want to use as extern and in a different header you declare it as extern "C" and then actually define the function in a .cpp file
EXAMPLE:
file main.xc
file enternfuncs.h
file enternfuncs.cpp
that's it. main.xc will be compiled in XC mode while enternfuncs.cpp will be compiled in C/C++ mode. this is good because now in the function definition you can use all the C++ you want, templates, inheritance, etc.
if you want, you can get rid of the redundancy by using some macros like this code that does the same thing:
file main.xc
file enternfuncs.h
file enternfuncs.cpp
here's how you do it:
in your .xc file declare the function you want to use as extern and in a different header you declare it as extern "C" and then actually define the function in a .cpp file
EXAMPLE:
file main.xc
Code: Select all
extern void myfunc(void);
void main(void)
{
myfunc();
}
Code: Select all
extern "C" void myfunc(void);
Code: Select all
void myfunc(void)
{
// your code here!
}
if you want, you can get rid of the redundancy by using some macros like this code that does the same thing:
file main.xc
Code: Select all
#include "enternfuncs.h"
void main(void)
{
myfunc();
}
Code: Select all
#ifdef __XC__
#define EXTERNAL extern
#else
#define EXTERNAL extern "C"
#endif
EXTERNAL void myfunc(void);
Code: Select all
void myfunc(void)
{
// your code here!
}
Last edited by Gravis on Tue Apr 24, 2012 8:45 pm, edited 1 time in total.
-
- XCore Expert
- Posts: 844
- Joined: Sun Jul 11, 2010 1:31 am
Code: Select all
extern "C"
Code: Select all
#include <xs1compat.h>
Code: Select all
extern "C" {
#include <xs1compat.h>
}
-
- XCore Addict
- Posts: 133
- Joined: Tue Dec 15, 2009 10:23 pm
Howdy!
So that (still) doesn't work for me as I get:
../src/main.xc: Error: L00067 Undefined reference to 'test'
what am I doing wrong??? All I have is a single function called 'test', which is nothing more than:
called from main.xc as:
where test.h contains:
both modules compile fine but for some reason the linker doesn't see it...
Rather odd and annoying that...
-Y
So that (still) doesn't work for me as I get:
../src/main.xc: Error: L00067 Undefined reference to 'test'
what am I doing wrong??? All I have is a single function called 'test', which is nothing more than:
Code: Select all
#include "test.h"
void test (void)
{
}
Code: Select all
#include "test.h"
void main ()
{
test ();
}
Code: Select all
extern void test (void);
Rather odd and annoying that...
-Y
-
- XCore Expert
- Posts: 844
- Joined: Sun Jul 11, 2010 1:31 am
Your test.cc should be like:
Also, you might need to link using the C++ compiler, not the XC compiler.
You didn't tell us what commands you used (hint hint), so that's about as detailed
as I can go ;-)
Code: Select all
extern "C" {
#include "test.h"
}
void test (void)
{
}
You didn't tell us what commands you used (hint hint), so that's about as detailed
as I can go ;-)
-
- XCore Addict
- Posts: 133
- Joined: Tue Dec 15, 2009 10:23 pm
I've tried using 'extern "C" ' but it barfs on the "C" part, so somewhere something's wrong. Note that this is using a brand-new project-from-template in the XDE, so settings weren't messed with *at all* :roll:
-Y
[edit] Only difference I can spot right now is that my file is a .cpp and yours is .cc, which might call a different linker?
-Y
[edit] Only difference I can spot right now is that my file is a .cpp and yours is .cc, which might call a different linker?
-
- Experienced Member
- Posts: 75
- Joined: Thu Feb 02, 2012 3:32 pm
I've made a header file to make function definition compatible for XC, C++ and C with ease. Using this header will allow you to call functions from XC, C++ and C.
the file is here:
or you can just copy this
here is an example of usage:
this header file will work for XC, C++ and C files. in fact, you can put the definition of read_channel() in asynchronous.xc, write_channel() in asynchronous.cpp and forward_channel() in asynchronous.c and it will compile and function properly. all you have to do is include asynchronous.h in each file.
one more thing, note the pointer style of the buffer. dont use a * because XC cant use them.
the file is here:
or you can just copy this
Code: Select all
#ifndef GLOBAL_H
#define GLOBAL_H
#include <platform.h>
#include <xs1.h>
#ifdef __XC__
# define EXTERNAL extern
#else
# include <xccompat.h>
typedef chanend chan;
# define streaming
# define in
# define out
# ifndef __cplusplus
# define EXTERNAL
# else
# define EXTERNAL extern "C"
# endif // __cplusplus
#endif // __XC__
#endif // GLOBAL_H
Code: Select all
#ifndef ASYNCHRONOUS_H
#define ASYNCHRONOUS_H
#include "global.h"
EXTERNAL void read_channel(chanend ichan, unsigned char buffer[], const unsigned int length);
EXTERNAL void write_channel(chanend ochan, const unsigned char buffer[], const unsigned int length);
EXTERNAL void forward_channel(chanend ichan, chanend ochan, unsigned int length);
#endif // _ASYNCHRONOUS_H
one more thing, note the pointer style of the buffer. dont use a * because XC cant use them.
-
- XCore Addict
- Posts: 133
- Joined: Tue Dec 15, 2009 10:23 pm
I'll give it a whirl later tonight...
FWIW, this kind of stuff should be a no-brainer to get this to work. Anyone new to XMOS and familiar with C/C++ is going to run into this problem and shouldn't have to go anywhere (i.e. here) to find answers..
Just saying'...
-Y
FWIW, this kind of stuff should be a no-brainer to get this to work. Anyone new to XMOS and familiar with C/C++ is going to run into this problem and shouldn't have to go anywhere (i.e. here) to find answers..
Just saying'...
-Y
-
- XCore Addict
- Posts: 133
- Joined: Tue Dec 15, 2009 10:23 pm
Gave it a quick whirl at work (ahem) and it does what it says on the tin, cheers for that!Gravis wrote:I've made a header file to make function definition compatible for XC, C++ and C with ease. Using this header will allow you to call functions from XC, C++ and C.
the file is here:
or you can just copy thishere is an example of usage:Code: Select all
#ifndef GLOBAL_H #define GLOBAL_H #include <platform.h> #include <xs1.h> #ifdef __XC__ # define EXTERNAL extern #else # include <xccompat.h> typedef chanend chan; # define streaming # define in # define out # ifndef __cplusplus # define EXTERNAL # else # define EXTERNAL extern "C" # endif // __cplusplus #endif // __XC__ #endif // GLOBAL_H
this header file will work for XC, C++ and C files. in fact, you can put the definition of read_channel() in asynchronous.xc, write_channel() in asynchronous.cpp and forward_channel() in asynchronous.c and it will compile and function properly. all you have to do is include asynchronous.h in each file.Code: Select all
#ifndef ASYNCHRONOUS_H #define ASYNCHRONOUS_H #include "global.h" EXTERNAL void read_channel(chanend ichan, unsigned char buffer[], const unsigned int length); EXTERNAL void write_channel(chanend ochan, const unsigned char buffer[], const unsigned int length); EXTERNAL void forward_channel(chanend ichan, chanend ochan, unsigned int length); #endif // _ASYNCHRONOUS_H
one more thing, note the pointer style of the buffer. dont use a * because XC cant use them.
As I said earlier, this is something that's fundamental to development and should work without having to wave dead chickens around and what not. Either make it part of the standard include file or modify the tools as people *will* rage-quit over something simple like this...
just my $0.02..
P.S. As a result, I'll be moving to command-line tools :-)
-
- XCore Expert
- Posts: 844
- Joined: Sun Jul 11, 2010 1:31 am
Strange, that sounds like you are not using a C++ compiler to compile thatyzoer wrote:I've tried using 'extern "C" ' but it barfs on the "C" part, so somewhere something's wrong.
C++ file -- but then again, your original error suggests you certainly do.
Actual command lines and error messages would help ;-)
It would be nice if things worked out of the box, sure :-)Note that this is using a brand-new project-from-template in the XDE, so settings weren't messed with *at all* :roll:
The linker never sees the source file, just the object file. It could be XDE only knowsOnly difference I can spot right now is that my file is a .cpp and yours is .cc, which might call a different linker?
what compiler to use for certain extensions, I have no idea, I never use XDE. Common
C++ source file name extensions are .C, .cc, .cxx, .cpp, and they all mean exactly the
same thing.