Using winrt::com_ptr<ID3D11Device1> with D3D11CreateDevice()? - c++

I've been studying the code from the DirectXTK example project and trying to implement it in a new project. It seems like Microsoft recommends using WinRT in new projects, though, so I decided I would try to switch instances of WRL::ComPtr to winrt::com_ptr. I'm stuck, though, trying to move between ID3D11Device1 in the project's Game class and ID3DDevice in D3D11CreateDevice().
Here's the example code, slightly abstracted for simplicity's sake:
ComPtr<ID3D11Device1> global_device;
void CreateDevice()
{
...
ComPtr<ID3D11Device> local_device;
ThrowIfFailed(D3D11CreateDevice( ... local_device.ReleaseAndGetAddressOf() ... ));
ThrowIfFailed(local_device.As(&global_device));
}
And here's my approximation of it with WinRT:
com_ptr<ID3D11Device1> global_device;
void createDevice()
{
...
com_ptr<ID3D11Device> local_device;
check_hresult(D3D11CreateDevice( ... local_device.put() ... ));
global_device = local_device.as<ID3D11Device1>();
}
Every time I run it, though, I get these errors:
Error C2664 'HRESULT IUnknown::QueryInterface(const IID &,void **)': cannot convert argument 1 from 'const winrt::guid' to 'const IID &' HelloDX11 .\x64\Debug\Generated Files\winrt\base.h 1955
Message No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called HelloDX11 .\x64\Debug\Generated Files\winrt\base.h 1955
Message Reason: cannot convert from 'const winrt::guid' to 'const IID' HelloDX11 .\x64\Debug\Generated Files\winrt\base.h 1955
Message see reference to function template instantiation 'winrt::com_ptr<ID3D11Device1> winrt::com_ptr<ID3D11Device>::as<ID3D11Device1>(void) const' being compiled HelloDX11 .\game.cpp 47
Message see reference to function template instantiation 'winrt::com_ptr<ID3D11Device1> winrt::impl::as<To,ID3D11Device>(From *)' being compiled
with
[
To=ID3D11Device1,
From=ID3D11Device
] HelloDX11 .\x64\Debug\Generated Files\winrt\base.h 2377
I've gone over the docs for WRL::ComPtr.As() here, the docs for winrt::com_ptr.as() here, and the "conversion" example here about as many times as I can stand at this point. What am I missing?

Answer per IInspectable's comment:
"winrt::guid converts to GUID, as long as you include Unknwn.h before you include any C++/WinRT headers." See: https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/news#news-and-changes-in-windows-sdk-version-100177630-windows-10-version-1809

Related

MSVC: unexpected token '__cdecl', expected 'expression'

Porting an application to Windows, I am now trying to compile it with VS2017 and am running into a host of problems. One of which is that a template wrapper I wrote to make a C++ member function available to be called from a C library (FUSE) doesn't work:
template <class T> class Callback {};
template <class T, class ...Arguments>
struct Callback<T(Arguments...)>
{
template <T(operations::*CALLBACK)(Arguments...)>
static T wrap(Arguments... parameters)
{
auto *instance = static_cast<operations*>(fuse_get_context()->private_data);
return (instance->*CALLBACK)(std::forward<Arguments>(parameters)...);
}
};
I am trying to set the callbacks like this in the constructor:
_operations.get_attr = Callback<std::remove_reference<decltype(*_high_level.getattr)>::type>::wrap<&operations::getattr>;
This is - I believe - valid code, but it doesn't comopile with some warnings and an error:
warning C4229: anachronism used: modifiers on data are ignored
error C2760: syntax error: unexpected token '__cdecl', expected 'expression'
note: see reference to function template instantiation 'T Callback<int (const char *,stat64_cygwin *)>::wrap<int operations::getattr(const char *,stat64_cygwin *)>(const char *,stat64_cygwin *)' being compiled
with
[
T=int
]
note: see reference to function template instantiation 'T Callback<int (const char *,stat64_cygwin *)>::wrap<int operations::getattr(const char *,stat64_cygwin *)>(const char *,stat64_cygwin *)' being compiled
with
[
T=int
]
error C2059: syntax error: '__cdecl'
The warning about anachronisms points to the line containing the template specifications for the wrap function. The error points to the line where the callback is actually invoked and returned, inside the wrap function.
It's very confusing, after reading somewhat I found that anachronisms are the sort-of attributes used in Windows APIs, which I don't use here, and I also don't have any __cdecl here. I have no idea how to proceed here.
Renaming CALLBACK to MEMFUNC worked. Apparantly, Windows defines CALLBACK to something unexpected, causing the code to be expanded in a way it doesn't compile.
Besides the fact that it's weird to just define random stuff like this (without prefixing it with WINDOWS_), it's unfortunate that the compiler generates errors which do not properly indicate that it originates in some #define, making it hard to debug.

how to deal with a c++ related warning in boost option header file?

i have Microsoft Visual Studio (MSVS) 2012 Pro and i have set warning level to a slightly elevated level of 4. when doing this i am getting warnings for some of the included header files from the boost library. the message is this:
C:\Users\****\boost/optional/optional.hpp(595): warning C4244: 'initializing' : conversion from 'T_DOUBLE' to 'float', possible loss of data
C:\Users\****\boost/optional/optional.hpp(430) : see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::construct<double>(Expr &&,const void *)' being compiled
with
[
T=T_FLOAT,
Expr=T_DOUBLE
]
C:\Users\****\boost/optional/optional.hpp(430) : see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::construct<double>(Expr &&,const void *)' being compiled
with
[
T=T_FLOAT,
Expr=T_DOUBLE
]
the code in the file leading to this warning is this (line 610 on most recent beta of boost 1.64.0.B2 still resembles it exactly - but i am not on the beta now):
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Constructs using any expression implicitly convertible to the single argument
// of a one-argument T constructor.
// Converting constructions of optional<T> from optional<U> uses this function with
// 'Expr' being of type 'U' and relying on a converting constructor of T from U.
template<class Expr>
void construct ( Expr&& expr, void const* )
{
new (m_storage.address()) value_type(boost::forward<Expr>(expr)) ;
m_initialized = true ;
}
what is the reason (=learn to understand) for this warning and how to eliminate it in the boost header for me any anyone else? alternatively thinking: does it make sense to "fix" it in such a global way, or is there a deeper meaning pointing rather to somewhere else (either boost or application codes) to improve or fix those other codes?
You are probably passing a double literal into method that expects float. Something like foo(1.0) instead of foo(1.0f)

How do I use std::bind when registering a function in Lua?

In the question How to register member function to lua without lua bind in c++ one answer suggested the following code:
class C {
public:
void blah(lua_State* L);
};
C inst;
lua_pushcclosure(L, std::bind(&C::blah, &inst, std::placeholder::_1), 0);
lua_setglobal(L, "blah");
(Quoted as it stood, including the small error in std::placeholders)
However, I cuold not get that to work. The error message I got back states that the function returned by std::bind can't be converted to a lua_CFunction.
I have also tried changing the return type of blah to int, but I get the same error message. If it's helpful to anyone, the full error message is:
Error C2664 'void lua_pushcclosure(lua_State *,lua_CFunction,int)': cannot convert argument 2 from 'std::_Binder<std::_Unforced,int (__thiscall C::* )(lua_State *),C *,const std::_Ph<1> &>' to 'lua_CFunction'
I even tried to change &C::blah to &inst.blah, but that unsurprisingly didn't work either.
Has anyone gotten it to work? Or is it just not meant to work?

Boost bind inside Boost packaged_task. Why boost asio thinks its not CompletionHandler?

So all my work happens inside of a class named thread_pool. This code will work no matter what run_item takes into itself:
template <class task_return_t>
void thread_pool::pool_item( boost::shared_ptr< boost::packaged_task<task_return_t> > pt)
{
internal_tasks.post(boost::bind(&thread_pool::run_item<task_return_t>, this, pt));
//...
This will not compile:
template <class task_return_t>
void thread_pool::pool_item( boost::shared_ptr< boost::packaged_task<task_return_t> > pt)
{
boost::packaged_task<void> task ( boost::bind(&thread_pool::run_item<task_return_t>, this, pt)));
internal_tasks.post( task);
Why? And how to make it compile?
I use boost 1.47.0. Errors my VS2010 talls me:
Error 6 error C2665: 'boost::asio::detail::zero_arg_handler_test' : none of the 2 overloads could convert all the argument types C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp 88 1 cf-server
Error 9 error C2664: 'void boost::asio::detail::task_io_service::post<CompletionHandler>(Handler)' : cannot convert parameter 1 from 'const boost::packaged_task<R>' to 'boost::packaged_task<R>' C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp 90 1 cf-server
Error 8 error C2664: 'T &boost::asio::detail::lvref<CompletionHandler>(T)' : cannot convert parameter 1 from 'const boost::packaged_task<R>' to 'boost::packaged_task<R>' C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp 88 1 cf-server
Error 7 error C2664: 'boost::asio::detail::clvref' : cannot convert parameter 1 from 'const boost::packaged_task<R>' to 'boost::packaged_task<R>' C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp 88 1 cf-server
It looks like the function thread_pool::run_item<task_return_t> accepts a non-const packaged task reference (or pointer) but boost::bind made a const copy, and is unable to pass the argument.
Without seeing the run_item signature, I can't tell exactly, but that's where I would look.
Edit: Looking a bit deeper (once I could get to a copy of boost 1_47), the problem is that boost::packaged_tasks are not copyable, however, boost::asio::io_service requires that CompletionHandler be CopyConstructable. Since boost::packaged_tasks are only MoveConstructable/MoveAssignable, you cannot pass them directly to the io_service.
See Boost.Asio requirements for CompletionHandlers

cvblob compile error in Visual C++ 6.0

I'm using Microsoft Visual C++ 6.0 and Microsoft Visual Studio 2008 to develop an academic computer vision project.
In this project i need to use OpenCV 1.1 (http://opencv.willowgarage.com/) and CvBlob (http://code.google.com/p/cvblob/).
I tried to compile this project with Microsoft Visual Studio 2008 and it compiles without errors.
With Visual C++ 6.0 i got a lot of errors.
OpenCV are not responsible of this behavior, because a trivial project with only OpenCV (without CvBlob) works well.
To understand the errors better I made an empty project with only the CvBlob inclusion.
I paste here a brief summary of the errors:
cvcontour.cpp(253) : error C2371: 'i' : redefinition; different basic types (and others similar to this. i solved with variable redefinition, every time)
cvcontour.cpp(318) : error C2664: 'thiscall std::vector<struct CvPoint,class std::allocator<struct CvPoint> >::std::vector<struct CvPoint,class std::allocator<struct CvPoint> >(unsigned int,const struct CvPoint &,const class std::allocator<struct CvPoint> &)' : cannot convert parameter 1 from 'class std::deque<struct CvPoint,class std::allocator<struct CvPoint> >::iterator' to 'unsigned int' No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
cvtrack.cpp(278) : error C2440: 'initializing' : cannot convert from 'struct cvb::CvTrack *const ' to 'struct cvb::CvBlob *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Have you ideas on how can i solve these problems?
Thanks in advance for the help!
-------- UPDATE --------
I tried to edit and correct the code in order to elminate the three errors in my question.
The error C2664 seems to be the more difficult to cirmumvent...
I have replaced the indicted line
return new CvContourPolygon(dq.begin(), dq.end());
where CvContourPolygon is a typedef std::vector<CvPoint> CvContourPolygon;
with
deque<int>::iterator dq_it;dq_it = dq.begin();
CvContourPolygon v_tmp;
v_tmp.push_back(*dq_it);
while (dq_it != dq.end()){
v_tmp.push_back(*dq_it++);
}
First, what that i wrote is correct? Than, how can i solve the errors that occured from this?
Thank you in advance!
Errors (suppose that the first line is 318:
cvcontour.cpp(319) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class std::deque<struct CvPoint,class std::allocator<struct CvPoint> >::iterator' (or
there is no acceptable conversion)
cvcontour.cpp(321) : error C2664: 'push_back' : cannot convert parameter 1 from 'int' to 'const struct CvPoint &'
Reason: cannot convert from 'int' to 'const struct CvPoint'
No constructor could take the source type, or constructor overload resolution was ambiguous
cvcontour.cpp(322) : error C2679: binary '!=' : no operator defined which takes a right-hand operand of type 'class std::deque<struct CvPoint,class std::allocator<struct CvPoint> >::iterator' (or there is no acceptable conversion)
cvcontour.cpp(322) : fatal error C1903: unable to recover from previous error(s); stopping compilation
Error executing cl.exe.
-------- UPDATE2 --------
This code seems to work correctly!
deque<CvPoint>::iterator dq_it;
dq_it = dq.begin();
CvContourPolygon v_tmp;
for (dq_it = dq.begin(); dq_it != dq.end(); ++dq_it){
v_tmp.push_back(*dq_it);
}
//return new CvContourPolygon(dq.begin(), dq.end());
return &v_tmp;
C2371 - VC6 was sloppy with scope of local variables. Should be able to fix this by making the code use variable names unambiguously.
C2664 - looks like failure to initialize a vector using deque iterators - wrong overload on vector::vector() being called? Probably have to work around this by manually copying the deque elements to the new vector somehow.
C2440 - check the objects are compatible (VS2008 seems to think so) and add the appropriate cast.
EDIT:
Shouldn't your code look like this?
deque<CVPoint>::iterator dq_it;dq_it = dq.begin();
CvContourPolygon v_tmp;
for (dq_it = dq.begin(); dq_it != dq.end(); ++dq_it)
{
v_tmp.push_back(*dq_it);
}