I'm using the pimpl-idiom with std::unique_ptr:
class window {
window(const rectangle& rect);
private:
class window_impl; // defined elsewhere
std::unique_ptr<window_impl> impl_; // won't compile
};
However, I get a compile error regarding the use of an incomplete type, on line 304 in <memory>:
Invalid application of 'sizeof' to an incomplete type 'uixx::window::window_impl'
For as far as I know, std::unique_ptr should be able to be used with an incomplete type. Is this a bug in libc++ or am I doing something wrong here?
Here are some examples of std::unique_ptr with incomplete types. The problem lies in destruction.
If you use pimpl with unique_ptr, you need to declare a destructor:
class foo
{
class impl;
std::unique_ptr<impl> impl_;
public:
foo(); // You may need a def. constructor to be defined elsewhere
~foo(); // Implement (with {}, or with = default;) where impl is complete
};
because otherwise the compiler generates a default one, and it needs a complete declaration of foo::impl for this.
If you have template constructors, then you're screwed, even if you don't construct the impl_ member:
template <typename T>
foo::foo(T bar)
{
// Here the compiler needs to know how to
// destroy impl_ in case an exception is
// thrown !
}
At namespace scope, using unique_ptr will not work either:
class impl;
std::unique_ptr<impl> impl_;
since the compiler must know here how to destroy this static duration object. A workaround is:
class impl;
struct ptr_impl : std::unique_ptr<impl>
{
~ptr_impl(); // Implement (empty body) elsewhere
} impl_;
As Alexandre C. mentioned, the problem comes down to window's destructor being implicitly defined in places where the type of window_impl is still incomplete. In addition to his solutions, another workaround that I've used is to declare a Deleter functor in the header:
// Foo.h
class FooImpl;
struct FooImplDeleter
{
void operator()(FooImpl *p);
};
class Foo
{
...
private:
std::unique_ptr<FooImpl, FooImplDeleter> impl_;
};
// Foo.cpp
...
void FooImplDeleter::operator()(FooImpl *p)
{
delete p;
}
Note that using a custom Deleter function precludes the use of std::make_unique (available from C++14), as already discussed here.
use a custom deleter
The problem is that unique_ptr<T> must call the destructor T::~T() in its own destructor, its move assignment operator, and unique_ptr::reset() member function (only). However, these must be called (implicitly or explicitly) in several PIMPL situations (already in the outer class's destructor and move assignment operator).
As already pointed out in another answer, one way to avoid that is to move all operations that require unique_ptr::~unique_ptr(), unique_ptr::operator=(unique_ptr&&), and unique_ptr::reset() into the source file where the pimpl helper class is actually defined.
However, this is rather inconvenient and defies the very point of the pimpl idoim to some degree. A much cleaner solution that avoids all that is to use a custom deleter and only move its definition into the source file where the pimple helper class lives. Here is a simple example:
// file.h
class foo
{
struct pimpl;
struct pimpl_deleter { void operator()(pimpl*) const; };
std::unique_ptr<pimpl,pimpl_deleter> m_pimpl;
public:
foo(some data);
foo(foo&&) = default; // no need to define this in file.cc
foo&operator=(foo&&) = default; // no need to define this in file.cc
//foo::~foo() auto-generated: no need to define this in file.cc
};
// file.cc
struct foo::pimpl
{
// lots of complicated code
};
void foo::pimpl_deleter::operator()(foo::pimpl*ptr) const { delete ptr; }
Instead of a separate deleter class, you can also use a free function or static member of foo:
class foo {
struct pimpl;
static void delete_pimpl(pimpl*);
using deleter = void(&)(pimpl*);
std::unique_ptr<pimpl,deleter> m_pimpl;
public:
foo(some data);
};
Probably you have some function bodies within .h file within class that uses incomplete type.
Make sure that within your .h for class window you have only function declaration. All function bodies for window must be in .cpp file. And for window_impl as well...
Btw, you have to explicitly add destructor declaration for windows class in your .h file.
But you CANNOT put empty dtor body in you header file:
class window {
virtual ~window() {};
}
Must be just a declaration:
class window {
virtual ~window();
}
To add to the other's replies about the custom deleter, in our internal "utilities library" I added a helper header to implement this common pattern (std::unique_ptr of an incomplete type, known only to some of the TU to e.g. avoid long compile times or to provide just an opaque handle to clients).
It provides the common scaffolding for this pattern: a custom deleter class that invokes an externally-defined deleter function, a type alias for a unique_ptr with this deleter class, and a macro to declare the deleter function in a TU that has a complete definition of the type. I think that this has some general usefulness, so here it is:
#ifndef CZU_UNIQUE_OPAQUE_HPP
#define CZU_UNIQUE_OPAQUE_HPP
#include <memory>
/**
Helper to define a `std::unique_ptr` that works just with a forward
declaration
The "regular" `std::unique_ptr<T>` requires the full definition of `T` to be
available, as it has to emit calls to `delete` in every TU that may use it.
A workaround to this problem is to have a `std::unique_ptr` with a custom
deleter, which is defined in a TU that knows the full definition of `T`.
This header standardizes and generalizes this trick. The usage is quite
simple:
- everywhere you would have used `std::unique_ptr<T>`, use
`czu::unique_opaque<T>`; it will work just fine with `T` being a forward
declaration;
- in a TU that knows the full definition of `T`, at top level invoke the
macro `CZU_DEFINE_OPAQUE_DELETER`; it will define the custom deleter used
by `czu::unique_opaque<T>`
*/
namespace czu {
template<typename T>
struct opaque_deleter {
void operator()(T *it) {
void opaque_deleter_hook(T *);
opaque_deleter_hook(it);
}
};
template<typename T>
using unique_opaque = std::unique_ptr<T, opaque_deleter<T>>;
}
/// Call at top level in a C++ file to enable type %T to be used in an %unique_opaque<T>
#define CZU_DEFINE_OPAQUE_DELETER(T) namespace czu { void opaque_deleter_hook(T *it) { delete it; } }
#endif
May be not a best solution, but sometimes you may use shared_ptr instead.
If course it's a bit an overkill, but... as for unique_ptr, I'll perhaps wait 10 years more until C++ standard makers will decide to use lambda as a deleter.
Another side.
Per your code it may happen, that on destruction stage window_impl will be incomplete. This could be a reason of undefined behaviour.
See this:
Why, really, deleting an incomplete type is undefined behaviour?
So, if possible I would define a very base object to all your objects, with virtual destructor. And you're almost good. You just should keep in mind that system will call virtual destructor for your pointer, so you should define it for every ancestor. You should also define base class in inheritance section as a virtual (see this for details).
Using extern template
The issue with using std::unique_ptr<T> where T is an incomplete type is that unique_ptr needs to be able to delete an instance of T for various operations. The class unique_ptr uses std::default_delete<T> to delete the instance. Hence, in an ideal world, we would just write
extern template class std::default_delete<T>;
to prevent std::default_delete<T> from being instantiated. Then, declaring
template class std::default_delete<T>;
at a place where T is complete, would instantiate the template.
The issue here is that default_delete actually defines inline methods that will not be instantiated. So, this idea does not work. We can, however, work around this problem.
First, let us define a deleter that does not inline the call operator.
/* --- opaque_ptr.hpp ------------------------------------------------------- */
#ifndef OPAQUE_PTR_HPP_
#define OPAQUE_PTR_HPP_
#include <memory>
template <typename T>
class opaque_delete {
public:
void operator() (T* ptr);
};
// Do not move this method into opaque_delete, or it will be inlined!
template <typename T>
void opaque_delete<T>::operator() (T* ptr) {
std::default_delete<T>()(ptr);
}
Furthermore, for ease of use, define a type opaque_ptr which combines unique_ptr with opaque_delete, and analogously to std::make_unique, we define make_opaque.
/* --- opaque_ptr.hpp cont. ------------------------------------------------- */
template <typename T>
using opaque_ptr = std::unique_ptr<T, opaque_delete<T>>;
template<typename T, typename... Args>
inline opaque_ptr<T> make_opaque(Args&&... args)
{
return opaque_ptr<T>(new T(std::forward<Args>(args)...));
}
#endif
The type opaque_delete can now be used with the extern template construction. Here is an example.
/* --- foo.hpp -------------------------------------------------------------- */
#ifndef FOO_HPP_
#define FOO_HPP_
#include "opaque_ptr.hpp"
class Foo {
public:
Foo(int n);
void print();
private:
struct Impl;
opaque_ptr<Impl> m_ptr;
};
// Do not instantiate opaque_delete.
extern template class opaque_delete<Foo::Impl>;
#endif
Since we prevent opaque_delete from being instantiated this code compiles without errors. To make the linker happy, we instantiate opaque_delete in our foo.cpp.
/* --- foo.cpp -------------------------------------------------------------- */
#include "foo.hpp"
#include <iostream>
struct Foo::Impl {
int n;
};
// Force instantiation of opaque_delete.
template class opaque_delete<Foo::Impl>;
The remaining methods could be implemented as follows.
/* --- foo.cpp cont. -------------------------------------------------------- */
Foo::Foo(int n)
: m_ptr(new Impl)
{
m_ptr->n = n;
}
void Foo::print() {
std::cout << "n = " << m_ptr->n << std::endl;
}
The advantage of this solution is that, once opaque_delete is defined, the required boilerplate code is rather small.
I am doing a C++/CX runtime wrapper, and I need pass C++/CX Object pointer to native C. How do I do it, and convert the native pointer back to C++/CX Object reference type?
void XClassA::do(XClass ^ B)
{
void * ptr = (void*)(B); // how to convert it?
}
And also, C++/CX uses Reference Counting, if I cast the Object reference to native pointer, how do I manage the pointer life cycle?
update (request from #Hans Passant)
Background of the question,
Native C
I am trying to use C++/CX wrap Native C library (not C++) as Windows Runtime Component. Native c has many callback functions which declared as the following,
for example,
//declare in native c
typedef int (GetData*)(void *, char* arg1, size_t arg2);
void * is a pointer to object instance.
and the callback will be executed in native c during runtime.
We expect Application(C#/C++CX ...) to implement the method.
WinRT wrapper (C++/CX)
my idea is the following,
(1) Provide interface to Application
// XRtWrapperNamespace
public interface class XWinRtDataWrapper
{
//declare in base class
void getData(IVector<byte> ^ data);
}
to let Application implement the function. As I cannot export native data type, I provide IVector to get data from Application.
(2) Declare a global callback function to convert IVector<byte>^ to native data type char *, like following,
// when Native C executes callback function,
// it will forward in the method in C++/CX.
// The method calls the implementation method via object pointer.
// (And here is my my question)
void XRtWrapperNamespace::callbackWrapper(void * ptr, char *, int length)
{
// create Vector to save "out" data
auto data = ref new Vector<byte>();
// I expect I could call the implementation from Application.
ptr->getData(data); // bad example.
// convert IVector data to char *
// ...
}
My question is
How do I keep windows object reference to native C?
It looks impossible, but any solution to do it?
Application (example)
//Application
public ref class XAppData: public XWinRtDataWrapper
{
public:
virtual void getData(IVector<byte> ^ data)
{
//implementation here
}
}
You are not on the right track. I'll assume you #include a c header in your component:
extern "C" {
#include "native.h"
}
And this header contains:
typedef int (* GetData)(void* buffer, int buflen);
void initialize(GetData callback);
Where the initialize() function must be called to initialize the C code, setting the callback function pointer. And that you want the client code to directly write into buffer whose allocated size is buflen. Some sort of error indication would be useful, as well as allowing the client code to specify how many bytes it actually wrote into the buffer. Thus the int return value.
The equivalent of function pointers in WinRT are delegates. So you'll want to declare one that matches your C function pointer in functionality. In your .cpp file write:
using namespace Platform;
namespace YourNamespace {
public delegate int GetDataDelegate(WriteOnlyArray<byte>^ buffer);
// More here...
}
There are two basic ways to let the client code use the delegate. You can add a method that lets the client set the delegate, equivalent to way initialize() works. Or you can raise an event, the more WinRT-centric way. I'll use an event. Note that instancing is an issue, their is no decent mapping from having multiple component objects to a single C function pointer. I'll gloss this over by declaring the event static. Writing the ref class declaration:
public ref class MyComponent sealed
{
public:
MyComponent();
static event GetDataDelegate^ GetData;
private:
static int GetDataImpl(void* buffer, int buflen);
};
The class constructor needs to initialize the C code:
MyComponent::MyComponent() {
initialize(GetDataImpl);
}
And we need the little adapter method that makes the C callback raise the event so the client code can fill the buffer:
int MyComponent::GetDataImpl(void* buffer, int buflen) {
return GetData(ArrayReference<byte>((byte*)buffer, buflen));
}
I have a file named "KernelUtil.cu" as follows
__device__ int add(int a, int b)
{
return a+b;
}
I have my main program which is "main.cu". I need to call the "add" function from here. How can I do it?? The following doesnt work.
#include "KernelUtil.cu"
__global__ void test()
{
int c = add(10,10);
}
int main()
{
test<<<1,1>>>();
}
giving an error add is already defined in main.cu
I expect that you have a rule that automatically compiles all .cu files, meaning KernelUtil.cu is effectively compiled twice, once on its own and once when included in main.cu, and therefore add is duplicated.
Try renaming KernelUtil.cu to KernelUtil.h (or .cuh).
Apologies for not being familiar with formatting on here...I've made
some progress thanks to helpful replies and edited and removed my original
question to be replaced by the current one.
My problem lies with converting a C struct or struct pointer to PyObject. There
is no alternative to this because I am wrapping an existing C library whose
callback requires a C struct pointer.
Following works but with limitations:
%module cain1
%{
typedef struct {
double price;
int volume;
} book_entry_t;
typedef struct {
char symbol[10];
book_entry_t *book;
} trade_t;
typedef void (*CALLBACK)(trade_t trade);
CALLBACK my_callback = 0;
static PyObject *my_pycallback = NULL;
static void bigSnake(trade_t trade)
{
PyObject *result;
PyObject *d1;
result = PyEval_CallObject(my_pycallback,
Py_BuildValue("(y#)",
(char*)&trade,
sizeof(trade_t)
)
);
Py_XDECREF(result);
return /*void*/;
}
void test_cb (PyObject *callMe1) {
trade_t d1;
book_entry_t b1;
b1.price = 123.45;
b1.volume = 99;
Py_XINCREF(callMe1); /* Add a reference to new callback */
my_pycallback = callMe1; /* Remember new callback */
strcpy (d1.symbol,"Gupta Ltd");
d1.book = &b1;
bigSnake(d1);
}
%}
// Expose in python module..
typedef struct {
double price;
int volume;
} book_entry_t;
typedef struct {
char symbol[10];
book_entry_t *book;
} trade_t;
void test_cb(PyObject *callMe1);
and then triggering the callback from Python:
import cain1
import struct
def dave(d1):
N1,N2 = struct.unpack('10sP', d1)
print ('\n %s: %x' % (N1.decode() ,N2))
price,volume = struct.unpack('di',N2)
print (price,volume)
def main():
cain1.test_cb(dave)
main()
but I am unable to recover the book_entry_t strcut contents pointed to by trade_t....
I just feel this is all too convoluted since I have the pointer to structs and there
must be a straightforward way for Python to use that without any fuss.
Py_BuildValue("(N)",details) expects a PyObject* (your "N" says so), and you pass it something very different. Try Py_BuildValue("(i)", details.index) instead, and change it to accomodate any changes in details_t.
You're attempting to build a PyObject from a details_t struct. This isn't valid. Either pass the callback an integer (seems easier since details_t only has the one field) OR create a proper PyObject type. You can't blindly cast one type to another and expect it to work (a PyObject is more than just a pointer).
I have this class defined in Global.h
class Global
{
public:
static string InttoStr(int num);
};
In Global.cpp, i have
Global::InttoStr(int num)
{
//Code To convert integer into string.
}
Now, from SubMove.cpp, when i call Global::InttoStr(num) I get following error:
error LNK2019: unresolved external symbol Global::InttoStr(int) referenced in function SubMove::toString(void)
Then I made the function non-static and called it like so:
Global g;
g.InttoStr(num);
But the error still persists.
I thought it had something to do with extern and searched it but i could not make any connection. Please help.
First off, try this:
string Global::InttoStr(int num)
{
//Code To convert integer into string.
}
Also, are you calling InttoStr from another library ? If so, you'll need to export the class "Global".
Best practice is to use a lib header (in the example below replace LIB_ with the name of the library):
#ifndef SOME_LIB_HEADER
#define SOME_LIB_HEADER
#if defined (LIB_EXPORTS)
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif // SOME_LIB_HEADER
Define LIB_EXPORTS in your project contianing Global, include the lib header in Global.h, then define the class like this
class LIB_API Global
{
// some code for the class definition
};
Each project should have its own LIB_EXPORTS and LIB_API definition like DLL1_EXPORTS, DLL1_API, DLL2_EXPORTS, DLL2_API etc.
Basically this makes a separate lib treat the previous dll with __declspec(dllimport) and resolve all externs.