Reason for segmentation fault, while using drag wxFileDropTarget - drag-and-drop

I try to do simple drag'n'drop (drag file to text area). I implemented drag'n'drop in 2 ways. Lets mark them V1 and V2.
In both versions drag'n'drop works OK, but in V1 I get segmentation fault when I try to exit the application.
Question:
Maybe somebody could enlighten me why with V1 I get segmentation faul, while no segmentation fault with V2 ?
(I have no real problem using V2, just want to know the reason why segmenation fault occurs)
Short descriptions of the versions:
V1 - There is one class named Notepad. It inherits from wxFrame and wxFileDropTarget, and encapsulates wxTextCtrl and implements OnDropFiles(
V2 - class Notepad ingerits only from wxFrame and encapsulates wxTextCtrl. Drang'n'drop is done by separate class called DRPTARGET, which inherits from wxFileDropTarget and implements OnDropFiles(
Code for ilustration
(I cut out a lot of code here, which was not relevant. I hope I did not cut out too much)
V1:
#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/dnd.h>
class Notepad : public wxFrame , public wxFileDropTarget {
public:
Notepad();
private:
wxTextCtrl* text_area;
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames);
};
bool Notepad::OnDropFiles (wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxArrayString &filenames){
return this->text_area->LoadFile(filenames[0]);
}
Notepad::Notepad() : wxFrame(NULL, wxID_ANY, wxT("V1"), wxDefaultPosition, wxSize(650,500)) {
wxBoxSizer *sizerh = new wxBoxSizer(wxHORIZONTAL);
this->text_area = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_MULTILINE);
sizerh->Add(this->text_area,1,wxEXPAND,0);
this->SetSizer(sizerh);
this->text_area->SetDropTarget(this);
}
V2:
#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/dnd.h>
class DRPTARGET : public wxFileDropTarget{
private:
wxTextCtrl* text_area;
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
{
return this->text_area->LoadFile(filenames[0]);
};
public:
DRPTARGET(wxTextCtrl* text_area)
{
this->text_area = text_area;
};
};
class Notepad : public wxFrame , public wxFileDropTarget {
public:
Notepad(); // our default constructor
private:
wxTextCtrl* text_area;
};
Notepad::Notepad() : wxFrame(NULL, wxID_ANY, wxT("V2"), wxDefaultPosition, wxSize(650,500)) {
wxBoxSizer *sizerh = new wxBoxSizer(wxHORIZONTAL);
this->text_area = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_MULTILINE);
sizerh->Add(this->text_area,1,wxEXPAND,0);
this->SetSizer(sizerh);
DRPTARGET* drop_target = new DRPTARGET(this->text_area);
this->text_area->SetDropTarget(drop_target);
}

When a drop target is registered, wxWidgets will be nice and delete the pointer after the it exits the main loop. The problem has to do with the scope of the file drop target object.
V1
this->text_area->SetDropTarget(this);
In this version, "this" refers to the frame. Remember that the window pointers are also managed by wxWidgets; the frame pointer is deleted before the file drop target. When wxWidgets tries to delete the drop target pointer it will attempt to delete a pointer that has already been deleted.
V2
DRPTARGET* drop_target = new DRPTARGET(this->text_area);
this->text_area->SetDropTarget(drop_target);
In this case, the pointer is allocated in the heap; but never deleted. In this case, when wxWidgets attempts to delete it it can do so safely.

Related

creating a Vulkan Instance in version 1.3.224 doesn't work and results in an Error VK_ERROR_INCOMPATIBLE_DRIVER on Apple M1

Hello I am new to Vulkan and c++.
I am following a tutorial on Vulkan for Visual-Studio and stuck at creating a Vulkan Instance. Through a lot of googling I found out that the error -9 (VK_ERROR_INCOMPATIBLE_DRIVER) is based on the Vulkan Version 1.3, me using MacOS and how it implements the MoltenVk or must be included or something else like that.
There it got too complicated for me.
I have tried to search through the documentations and now I don't really even understand what MoltenVk is or how I even tried to include Vulkan with cmake in my project.
I may found a solution on [here] and on stackoverflow (Why does vkCreateInstance return "VK_ERROR_INCOMPATIBLE_DRIVER" on MacOS despite vulkan supported GPU and up to date driver?) but I am not able to implement/understand it. Maybe somebody can explain it or tell me how to implement it?.
The Site said I should put something like that in
std::vector<const char*>
extNames.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
extNames.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
VkInstanceCreateInfo inst_info = {};
ins_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
inst_info.enabledExtensionCount = static_cast<uint32_t>(extNames.size());
inst_info.ppEnabledExtensionNames = extNames.data();
I have tried it that way and with some deviations in the vk_device.cpp file without any success.
My Project basically looks like this:
Project
--.vscode
--bin
->Project.exe
--build
--CMakeFiles
--libs
--SDL
--src
--Vk_base
->vk_base.h
->vk_device.cpp
->main.cpp
->CMakeList.txt
vk_base.h:
#include <vulkan/vulkan.h>
struct VulkanContext {
VkInstance instance;
};
VulkanContext* initVulkan();
vk_device.cpp:
#include "vk_base.h"
#include <iostream>
bool initVulkanInstance(VulkanContext* context) {
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Vulkan App";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "No Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_VERSION_1_0;
VkInstanceCreateInfo createInfo = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
createInfo.pApplicationInfo = &appInfo;
createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; // MAC OS SPECIFIC
//createInfo.enabledExtensionCount = static_cast<uint32_t>(extNames.size()); // MAC OS SPECIFIC
//createInfo.ppEnabledExtensionNames = extNames.data(); // MAC OS SPECIFIC
VkResult creation_result = vkCreateInstance(&createInfo, 0, &context->instance);
std::cout << creation_result << std::endl;
return true;
}
VulkanContext* initVulkan() {
VulkanContext* context = new VulkanContext();
if (initVulkanInstance(context) != VK_SUCCESS) {
throw std::runtime_error("failed to create instance!");
}
return context;
}
main.cpp
#include <iostream>
#include <SDL.h>
#include "vk_base/vk_base.h"
bool handleMessage() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
return false;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {
return false;
}
break;
}
}
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *_window;
_window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 700, 500, SDL_WINDOW_RESIZABLE);
SDL_Event e;
bool quit = false;
while (!quit) {
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
}
}
}
VulkanContext* context = initVulkan();
SDL_DestroyWindow(_window);
SDL_Quit();
return 0;
}
and my Cmakefile to create the Project in the build folder with the command : cmake ../ -GXcode ( I have tried it with -GXcode and without)
CMakeLists.txt:
#project name
project(Project)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
set(SOURCE_FILES src/main.cpp src/vk_base/vk_device.cpp)
#find SDL2
add_subdirectory(libs/SDL)
#find Vulkan
find_package(Vulkan REQUIRED)
#vulkan executebl
add_executable(Project ${SOURCE_FILES})
target_include_directories(Project PUBLIC libs/SDL/include)
target_link_libraries(Project PUBLIC SDL2-static)
target_link_libraries(Project PUBLIC Vulkan::Vulkan)
target_link_libraries(Project PUBLIC ${Vulkan_LIBRARIES})
Thank you for reading and sry for my bad english:)
if there are misspellings in it, it is probably not the cause of the problem and just a typo from me on this thread :p
if you are not comfortable with C++, steer away from Vulkan. One will teach you exactly the wrong lessons about the other. Vulkan is low-level API, and shows you how you should not be programming C++ in 98 % of the time.
Apple does not support Vulkan. They have their own API Metal. MoltenVK is a library that attempts to translate Vulkan function calls to Metal calls.
This API translation does not match 1:1, so the MoltenVK wrapper is not a conformant Vulkan implementation. You need to waive that it is not conformant, and that you know of and will avoid triggering the limitations:
https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VK_KHR_portability_subset
https://github.com/KhronosGroup/MoltenVK/blob/master/Docs/MoltenVK_Runtime_UserGuide.md#known-moltenvk-limitations
You waive the Vulkan conformance by adding VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit to the Instance creation:
#ifdef __APPLE__
createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif //__APPLE__
VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR is part of a Vulkan extension, so that extension needs to be enabled before using the bit, per standard Vulkan rules:
#ifdef __APPLE__
extNames.push_back( VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME );
#endif //__APPLE__
createInfo.enabledExtensionCount = static_cast<uint32_t>(extNames.size());
createInfo.ppEnabledExtensionNames = extNames.data();

jxcore crashed at JX_CreateEmptyObject in sub instance creation thread

I am currently working on embedding jxcore to my robotic system program.When i am testing embedding api ,i produced the following code:
#include "stdafx.h"
#include "ScriptEngine.h"
#include <windows.h>
#include "thread"
#include "mutex"
int main(int argc, char **args) {
char* homeFolder = args[0];
JX_InitializeOnce(homeFolder);
JX_InitializeNewEngine();
JX_DefineMainFile("console.log('parent engine')");
JXValue obj;
// Parent engine created at main thread ,and JX_CreateEmptyObject worked ok!
JX_CreateEmptyObject(&obj);
JXValue global;
JX_GetGlobalObject(&global);
JX_SetNamedProperty(&global, "NativeBridge", &obj);
JX_Free(&obj);
JX_Free(&global);
JX_StartEngine();
//create a new engine instance and attach it to a new thread
thread t1 (create_new_engine);
t1.join();
Sleep(10 * 1000);
}
void create_new_engine() {
string homeFolder = "";
JX_InitializeNewEngine();
JX_DefineMainFile("console.log('sub engine')");
JX_StartEngine();
JXValue obj1;
// sub engine created at new thread ,and JX_CreateEmptyObject called fail!
//Exception thrown: read access violation.
//__imp_TlsGetValue(...) returned nullptr.
//program break at :
//JXCORE_EXTERN(bool)
//JX_CreateEmptyObject(JXValue *value) {
// node::commons *com = node::commons::getInstance();
JX_CreateEmptyObject(&obj1);
JXValue global;
JX_GetGlobalObject(&global);
JX_SetNamedProperty(&global, "NativeBridge", &obj1);
JX_Free(&obj1);
JX_Free(&global);
JX_Loop();
JX_StopEngine();
}
My working enviroment is : windows 10 ,visual studio 2015,runing in vm fusion on mac
Thanks.

ensuring data-consistency of object

I'm having a problem with data-consistencies of objects e.g. how to deal with objects that get deleted while the user still has a reference to them.
simple pseudo-code example
node = graph.getNode(name)
node.destroy() < -- node gets destroyed
#or
graph.destroyNode(name)
node.getName() #<-- should complain that we're trying to reference an object that does not exist any more
a simple pseudo-code example would be
struct Node
{
/*...*/
};
typedef boost::shared_ptr<Node> NodePtr;
struct Graph
{
std::map<std::string,NodePtr> nodeMap;
NodePtr getNode(std::string name);
void removeNode(std::string name);
/*...*/
};
typedef boost::shared_ptr<Graph> GraphPtr;
// wrapper arround the the getNode function
object Graph_getNode( object obj, const std::string& key )
{
GraphPtr graphPtr = extract< GraphPtr >(obj);
return boost::python::api::object(graphPtr->getNode(key));
};
class_< Node,boost::noncopyable, NodePtr >( "Node", "node", no_init )
/*....*/
class_< Graph, bases<Node>, boost::noncopyable, GraphPtr >( "Graph", "graph", no_init )
.def("getNode", Graph_getNode, "get a node if it exists")
/*....*/
Are there any functions that I could define which are run on a Node-object every time it gets used where I could check if it is still valid ?
I hope this information is sufficient to understand my problem,
... thanks for reading!
Seb
As Node is exposed as being held by a boost::shared_ptr, the instance's lifetime can be affected by both C++ and Python. Python will keep the C++ Node object alive as long as a handle to the Python object holding the boost::shared_ptr exists.
Therefore, in the following code, lets start with the precondition that a Node named spam is held in graph. The code is annotated with the reference count for the C++ Node instance, as well as the Python Node instance.
# The node named 'spam' is held in
# graph's nodeMap.
# cpp count: 1; python count: 0
# Boost.Python creats a Python Node object
# that holds boost::shared_ptr<Node>.
node = graph.getNode('spam') # cpp count: 2; python count: 1
# Removes the boost::shared_ptr<Node> for
# 'spam' from graph.nodeMap.
graph.destroyNode('spam') # cpp count: 1; python count: 1
# The C++ Node is still alive because the
# Python Node holds a boost::shared_ptr<Node>
node.getName() # cpp count: 1; python count: 1
# When Python no longer has a handle to the
# Python Node object, it will be garbage
# collected, which in turn will destroy
# the held boost::shared_ptr<Node>
node = None # cpp count: 0; python count: 0
If node.getName() should not operate successfully on a destroyed node, then consider explicitly managing state. For example, node.destroy() would set state within node, and member-functions would check state before performing operations. If the state indicates the node has been destroyed, then raise an exception or handle it appropriately.
Here is a basic example demonstrating the lifetime:
#include <map>
#include <string>
#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
class Node
{
public:
Node(std::string name)
: name_(name)
{
std::cout << "Node()" << std::endl;
}
~Node()
{
std::cout << "~Node()" << std::endl;
}
std::string name() { return name_; }
private:
std::string name_;
};
class Graph
{
public:
// #brief Add node by name.
void add_node(std::string name)
{
nodes_.insert(make_pair(name, boost::make_shared<Node>(name)));
}
/// #brief Destroy node by name.
void destroy_node(std::string name)
{
nodes_.erase(name);
}
// #brief Get node by name.
boost::shared_ptr<Node> get_node(std::string name)
{
nodes_type::iterator result = nodes_.find(name);
return (result != nodes_.end())
? result->second
: boost::shared_ptr<Node>();
}
private:
typedef std::map<std::string, boost::shared_ptr<Node> > nodes_type;
nodes_type nodes_;
};
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<Node, boost::shared_ptr<Node>,
boost::noncopyable>("Node", python::no_init)
.def("name", &Node::name)
;
python::class_<Graph, boost::noncopyable>("Graph")
.def("add_node", &Graph::add_node)
.def("get_node", &Graph::get_node)
.def("destroy_node", &Graph::destroy_node)
;
}
And its usage in Python:
>>> from example import Graph
>>> graph = Graph()
>>> graph.add_node('spam')
Node()
>>> node = graph.get_node('spam')
>>> print node.name()
spam
>>> graph.destroy_node('spam')
>>> print node.name()
spam
>>> graph = None
>>> node = None
~Node()
Note how Node's destructor was only invoked once Python no longer had a handle to the object.

to get no. of bytes received and sent in cascades bb 10

Im new to cascades programming. Im trying to develop an app that could give me the number of bytes received and sent.
Im using QnetworkSession methods bytesReceived() and bytesWritten() for it, but getting errors.
Any help would be appreciable.
Thanks
Code:
#include "Monitor.hpp"
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <QtCore/QFile>
#include <QtNetwork/QNetworkSession>
#include <QtNetwork/QNetworkConfiguration>
#include <QtNetwork/QNetworkConfigurationManager>
using namespace bb::cascades;
QNetworkSession::QNetworkSession ( const QNetworkConfiguration & connectionConfig, QObject * parent = 0 );
Monitor::Monitor(bb::cascades::Application *app)
: QObject(app)
{
QNetworkSession qnetworksession;
// create scene document from main.qml asset
// set parent to created document to ensure it exists for the whole application lifetime
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
qml->setContextProperty("app", this);
// create root object for the UI
AbstractPane *root = qml->createRootObject<AbstractPane>();
// set created root object as a scene
app->setScene(root);
}
quint64 Monitor::Received() const
{
quint64 rec=qnetworksession.bytesReceived ();
return(rec);
}
quint64 Monitor::Sent() const
{
quint64 sen=qnetworksession.bytesWritten ();
return(sen);
}

How to expose aligned class with boost.python

When trying to expose aligned class like this:
class __declspec(align(16)) foo
{
public:
void foo_method() {}
};
BOOST_PYTHON_MODULE(foo_module)
{
class_<foo>("foo")
.def("foo_method", &foo::foo_method);
}
You end up with error (msvs 2010):
error C2719: 'unnamed-parameter': formal parameter with __declspec(align('16')) won't be aligned,
see reference to class template instantiation 'boost::python::converter::as_to_python_function<T,ToPython>' being compiled
The solution I found so far, is to use smart pointer to store object:
BOOST_PYTHON_MODULE(foo_module)
{
class_<foo, boost::shared_ptr<foo>, boost::noncopyable>("foo")
.def("foo_method", &foo::foo_method);
}
Isn't there a better solution? This is quite annoying, because you should wrap all your functions returning objects by value to return smart pointers instead, and performance also degrades.
I had the same problem and wanted a solution that doesn't involve shared_ptr. It involves specializing some boost::python classes to make sure we get a storage area big enough to be able to align our object within it.
I have written a somewhat long blog post explaining how I arrived at this solution here. Below is the solution I found. I feel it is quite a hack, so maybe it will break other things. But so far it seems to work and I haven't found anything better.
I was trying to expose an Eigen::Quaternionf (which requires 16 bytes alignment) :
bp::class_<Quaternionf>("Quaternion", bp::init<float, float, float, float>())
.def(bp::init<Matrix3f>())
.add_property("w", get_prop_const(&Quaternionf::w))
.add_property("x", get_prop_const(&Quaternionf::x))
.add_property("y", get_prop_const(&Quaternionf::y))
.add_property("z", get_prop_const(&Quaternionf::z))
.def("matrix", &Quaternionf::matrix)
.def("rotvec", &quaternion_to_rotvec);
The solution involves specializing 3 classes :
boost::python::objects::instance to request 16 bytes more than what our type requires to ensure we can align
...
union
{
align_t align;
char bytes[sizeof(Data) + 16];
} storage;
...
boost::python::objects::make_instance_impl to correctly set the Py_SIZE of our instance
...
Holder* holder = Derived::construct(
&instance->storage, (PyObject*)instance, x);
holder->install(raw_result);
// Note the position of the internally-stored Holder,
// for the sake of destruction
// Since the holder not necessarily allocated at the start of
// storage (to respect alignment), we have to add the holder
// offset relative to storage
size_t holder_offset = reinterpret_cast<size_t>(holder)
- reinterpret_cast<size_t>(&instance->storage)
+ offsetof(instance_t, storage);
Py_SIZE(instance) = holder_offset;
...
boost::python::objects::make_instance so that the construct method will align the holder in the storage
...
static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper<Quaternionf const> x)
{
// From the specialized make_instance_impl above, we are guaranteed to
// be able to align our storage
void* aligned_storage = reinterpret_cast<void*>(
(reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);
QuaternionfHolder* new_holder = new (aligned_storage)
QuaternionfHolder(instance, x);
return new_holder;
}
...
The full code is below :
typedef bp::objects::value_holder<Eigen::Quaternionf> QuaternionfHolder;
namespace boost { namespace python { namespace objects {
using namespace Eigen;
//template <class Data = char>
template<>
struct instance<QuaternionfHolder>
{
typedef QuaternionfHolder Data;
PyObject_VAR_HEAD
PyObject* dict;
PyObject* weakrefs;
instance_holder* objects;
typedef typename type_with_alignment<
::boost::alignment_of<Data>::value
>::type align_t;
union
{
align_t align;
char bytes[sizeof(Data) + 16];
} storage;
};
// Adapted from boost/python/object/make_instance.hpp
//template <class T, class Holder, class Derived>
template<class Derived>
struct make_instance_impl<Quaternionf, QuaternionfHolder, Derived>
{
typedef Quaternionf T;
typedef QuaternionfHolder Holder;
typedef objects::instance<Holder> instance_t;
template <class Arg>
static inline PyObject* execute(Arg& x)
{
BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >));
PyTypeObject* type = Derived::get_class_object(x);
if (type == 0)
return python::detail::none();
PyObject* raw_result = type->tp_alloc(
type, objects::additional_instance_size<Holder>::value);
if (raw_result != 0)
{
python::detail::decref_guard protect(raw_result);
instance_t* instance = (instance_t*)raw_result;
// construct the new C++ object and install the pointer
// in the Python object.
//Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result);
Holder* holder = Derived::construct(
&instance->storage, (PyObject*)instance, x);
holder->install(raw_result);
// Note the position of the internally-stored Holder,
// for the sake of destruction
// Since the holder not necessarily allocated at the start of
// storage (to respect alignment), we have to add the holder
// offset relative to storage
size_t holder_offset = reinterpret_cast<size_t>(holder)
- reinterpret_cast<size_t>(&instance->storage)
+ offsetof(instance_t, storage);
Py_SIZE(instance) = holder_offset;
// Release ownership of the python object
protect.cancel();
}
return raw_result;
}
};
//template <class T, class Holder>
template<>
struct make_instance<Quaternionf, QuaternionfHolder>
: make_instance_impl<Quaternionf, QuaternionfHolder, make_instance<Quaternionf,QuaternionfHolder> >
{
template <class U>
static inline PyTypeObject* get_class_object(U&)
{
return converter::registered<Quaternionf>::converters.get_class_object();
}
static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper<Quaternionf const> x)
{
LOG(INFO) << "Into make_instance";
LOG(INFO) << "storage : " << storage;
LOG(INFO) << "&x : " << x.get_pointer();
LOG(INFO) << "&x alignment (0 = aligned): " << (reinterpret_cast<size_t>(x.get_pointer()) & 0xf);
// From the specialized make_instance_impl above, we are guaranteed to
// be able to align our storage
void* aligned_storage = reinterpret_cast<void*>(
(reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);
QuaternionfHolder* new_holder = new (aligned_storage) QuaternionfHolder(instance, x);
LOG(INFO) << "&new_holder : " << new_holder;
return new_holder;
//return new (storage) QuaternionfHolder(instance, x);
}
};
}}} // namespace boost::python::objects