Using channels and ports in C/C++
From XCore Exchange
Currently ports and channel interaction in C or C++ has to be achieved by the user writing their own XC functions that can handle the various operations they require. These XC functions can then be called from C or C++ when needed.
Channel and Port Types in C/C++
You can have a channel as an argument to a C function by using the 'xccompat.h' include. For example:
#include <xccompat.h>
#include "channel_funcs.h"
void c_func( chanend c )
{
unsigned v;
while (1)
{
xc_channel_out(c, v);
v = xc_channel_in( c );
}
}
Where the channel interaction functions would be defined in 'channel_funcs.xc' such as:
void xc_channel_out(chanend c, unsigned v)
{
c <: v;
}
Name mangling
To avoid name mangling with C++, you need to give the C++ functions called from XC, C linkage. For example, the header 'channel_funcs.h', for the C++ file channel_funcs.ccp would be:
#ifdef __cplusplus
extern "C" {
#endif
void cpp_func(chanend c);
#ifdef __cplusplus
}
#endif
For more information on mixing C and C++ see [1].
Passing Streaming Channels to C Functions
Using the <xccompat.h> header, you can easily pass channels into C functions as it has a typedef for the chanend type. However, if you have a streaming channel in XC and want to pass that to a C function, your code will not compile. The 'streaming' modifier is unknown and you'll get various errors such as:
error: conversion from transmissive type requested function xyz changes streaming qualifier of type
The solution is very simple. You need to add:
- define streaming
directly after your C source file include of the xccompat.h file:
#include <xccompat.h> #define streaming
Your C code needs to know implicitly that the channel is a streaming type and treat it as such - no handshake token, etc. Similar to the examples above with a C program calling an XC function with a channel, you can call an XC function with a streaming channel.
In your XC, you can use:
// channel function called from C
// lets a C function that deals with pointers, floats and other things XC can't
// stuff a channel from C
void xc_channel_out(streaming chanend c, unsigned v)
{
c <: v;
}
In your C code, you need to define the XC function prototype:
extern void xc_channel_out(streaming chanend c, unsigned v);
in order to call back into XC with a streaming channel.
