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

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?

Related

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

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

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.

C++ Defining function pointer

I am trying to create a function pointer to another function in c++.
This is what I have so far:
LONG (*function)(LPSTR,LPVIPERVAR4,LONG)=&CWilExtender::DllVarHandler;
When I try to compile my program, I get this error:
.\MyExtender.cpp(132) : error C2440: 'initializing' : cannot convert from
'LONG (__thiscall CWilExtender::* )(LPSTR,LPVIPERVAR4,LONG)' to
'LONG (__cdecl *)(LPSTR,LPVIPERVAR4,LONG)'
There is no context in which this conversion is possible
I don't know how the DllVarHandler was defined, and I don't know how to reproduce the type for the function pointer.
How do I change the (_cdecl *) to match (__thisscall CWilExtender::*)?
Specifically, what does LONG (__thiscall CWilExtender::* )(LPSTR,LPVIPERVAR4,LONG) mean and how do I write that as the function pointer's type?
Thanks.
Thanks to the comments by #OliCharlesworth and #user814628, I solved my problem.
The correct code should be:
LONG (CWilExtender::* function)(LPSTR,LPVIPERVAR4,LONG)=&CWilExtender::DllVarHandler;
Thanks for being so quick to help!

Error 2664 - Can't convert from std::vector<...> to std::tr1::shared_ptr

Need help with an error message that I just can't figure out. I am getting the following:
Error 1 error C2664: 'void std::vector<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'Physics::Box2D' to 'std::tr1::shared_ptr<_Ty> &&' d:\visual studio 2010\projects\c++\test001\main.cpp 31 1 Test001
Not sure why, the code should work. I found sample code on StackOverFlow.com Maybe I am missing something.
Please help...newbie boost library user
//this code works fine...
Box2D *b = new Box2D();
b->Info();
//but this code fails...
vector< shared_ptr<Box2D> > boxes;
boxes.push_back( new Box2D() ); <--error happens here
The constructor for std::shared_ptr<T> taking a pointer to T is explicit, i.e. you can't implicitly convert to this type. Also, the error message doesn't seem to match the code. However, try this:
boxes.push_back(std::shared_ptr<Box2D>(new Box2D()));
... or
boxes.push_back(std::make_shared<Box2D>());

Cannot seem to come up with right parameter for _set_se_translator

I am trying to implement _set_se_translator. I tried to write a function with the following signature (from my .cpp file - of course, I have a similar signature in my .h file):
void CIntersonBScan::trans_func(unsigned int u, EXCEPTION_POINTERS* pExp)
I then pass this function as a parameter to _set_se_translator by writing the following code:
_set_se_translator(&CIntersonBScan::trans_func);
I then compile my code and get the following error message:
error C2664: '_set_se_translator': cannot convert parameter 1 from 'void(__thiscall CIntersonBScan::*)(unsigned int,EXCEPTION_POINTERS *)' to '_se_translator_function'
In the eh.h file, I found the following definition for _se_translator_function:
typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS*);
I tried varying the signature of trans_func and still got the same error message. I already set the /EHa compile option. How to I create a function that would actually match the signature of _se_translator_function?
typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS*);
This must be a free function, or a static member function - it cannot be a non-static member function (because these have a hidden implicit this parameter - and cannot match _se_translator_function).
It needs to be a free standing function, not a member function. That is why the types don't match.