Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"C linkage function cannot return C++ class" in Visual Studio 2019

I have the following function:

class Foo;

template <typename T>
struct PyArray1D{
    std::size_t size;
    T *array;
};

extern "C" PyArray1D<Foo> SimulatePhotonEvents() 
{
    Foo * foo = new Foo(); 
    return {1, foo}
}

However this does not compile using VS2019 (however it does with gcc) with the warning

C linkage function cannot return C++ class

However it does work when the template argument is a double for example... I can return a 'PyArray1D', without VS complaining.

So I added a new struct:

struct FooArray {
    std::size_t size;
    Foo *data;
};

And return this from the extern C function.

extern "C" FooArray SimulatePhotonEvents() 
{
    Foo * foo = new Foo(); 
    return {1, foo}
}

And to my big surprise this worked! My question is, why?

Isn't VS smart enough to see that the FooArray get's created out of the template function? And are there other, less hacky ways to solve this?

like image 595
Frank Avatar asked Aug 09 '19 11:08

Frank


1 Answers

You can make this compile by adding an explicit template specialization for PyArray1D<Foo> to your code:

template struct PyArray1D<Foo>;

I don't actually know why. I guess the compiler is not able to see the template, if it is not explicitly specialized, while parsing the extern declaration

like image 74
MofX Avatar answered Sep 25 '22 17:09

MofX