C++ interworking

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

C++ interworking

Post by Jamie »

It could be that I'm doing something silly, but I can't see it. I'm trying to call a C++ function from an XC program as follows:

main.xc:

Code: Select all

#include "functions.h"

int main(void) {
    chan c;
    par {
        send(c);
        receive(c);
    }
    return 0;
}
functions.h:

Code: Select all

void send(chanend c);
void receive(chanend c);
functions.cpp:

Code: Select all

#include <xccompat.h>
#include "channels.h"

void send(chanend c) {
    while(1) {
        chanOut(c, 0);
    }
}

void receive(chanend c) {
    while(1) {
        chanIn(c);
    }
}
channels.h:

Code: Select all

void chanOut(chanend c, unsigned v);
void chanIn(chanend c);
channels.xc:

Code: Select all

#include "channels.h"

void chanOut(chanend c, unsigned v) {
    c <: v;
}

void chanIn(chanend c) {
    unsigned v;
    c :> v;
}
Build:

Code: Select all

xcc -target=XC-1 -c channels.xc
xcc -target=XC-1 -c main.xc
xcc -target=XC-1 -std=c++98 -c functions.cpp
xcc -target=XC-1 main.o functions.o channels.o
Gives the error:

Code: Select all

xmap: Error: Value of undefined resource symbol "send.nstackwords" cannot be determined.
xmap: Error: Symbol "send.nstackwords" for resolution of resource expression for ".LLNK6" is undefined.
Then commenting out sender and receiver from the main par gives:

Code: Select all

functions.cpp: Error: Undefined reference to '_Z6chanInj'
functions.cpp: Error: Undefined reference to '_Z7chanOutjj'
Does anyone have any ideas?
You do not have the required permissions to view the files attached to this post.


richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

You need to give the c++ function you want to call C linkage to avoid C++ name mangling. For example you can change functions.h as follows:

Code: Select all

#ifdef __cplusplus
extern "C" {
#endif

void send(chanend c);
void receive(chanend c);

#ifdef __cplusplus
} // extern "C"
#endif
You would run into exactly the same problem if you tried to call between C and C++ without the extern "C" construct, for example see http://www.parashift.com/c++-faq-lite/m ... d-cpp.html
User avatar
monk_is_batman
Active Member
Posts: 38
Joined: Wed Jun 09, 2010 3:20 am
Location: Maine, USA

Post by monk_is_batman »

You'll also need include the header file functions.h in your functions.cpp file. As well as make the same changes to your channels.h, I've attached the project I was working in trying to get this work in. It compiles for me.
You do not have the required permissions to view the files attached to this post.
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Post by Jamie »

You need to give the c++ function you want to call C linkage to avoid C++ name mangling.
Oh okay. I didn't know about that happening... Thanks though, all working now :)