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

1

7

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?

Buttermilk answered 9/8, 2019 at 11:26 Comment(1)
It is all about the Application Binary Inteface POD types. If you'd like to use you'r code from C - you'd better replace Foo *data; with void* or struct Foo *;Cowell
S
5

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

Sapling answered 9/8, 2019 at 11:50 Comment(2)
How might one make this work with STL classes, e.g. unordered_map?Connacht
also see #6376382Inweave

© 2022 - 2024 — McMap. All rights reserved.