bitslip Posted December 7, 2019 Share Posted December 7, 2019 Hello, While trying to compile (a modified version of) the 18.2 Zybo PCAM 5 demo inside the SDK I got the following error: no matches converting function 'MyCallback' to type 'XIicPs_IntrHandler {aka void (*)(void*, long unsigned int)}' The error pointed to the following line of code in a file named PS_IIC.h : XIicPs_SetStatusHandler (&drv_inst_, &stat_handler_, &MyCallback<void(int)>); Please explain this error. Notes: 1. The Vivado project compiled correctly and the hardware was exported successfully to the SDK. 2. The PS_IIC.h file and a snapshot of the error message are attached. PS_IIC.h Link to comment Share on other sites More sharing options...
Ana-Maria Balas Posted December 18, 2019 Share Posted December 18, 2019 Hello @bitslip, What do you mean with a modified version of the 18.2 Zybo PCAM 5 demo ? Also did you use the last version of the demo project from github? Link to comment Share on other sites More sharing options...
bitslip Posted December 18, 2019 Author Share Posted December 18, 2019 Hi Ana-Maria, 10 days past since my last post - so I was beginning to loose hope... Thanks for stepping in. Quote did you use the last version of the demo project from github? Yes I did. By "modified version" I mean that I changed the logic design in Vivado and re-exported the hardware to SDK. When I tried to re-compile the C code inside SDK - I got many errors in various C and Header files. I managed to fix all - except of the one in this post. Link to comment Share on other sites More sharing options...
elodg Posted December 18, 2019 Share Posted December 18, 2019 Because it's C++ code, not C. You need to select the right project type when re-creating the application. Link to comment Share on other sites More sharing options...
bitslip Posted December 18, 2019 Author Share Posted December 18, 2019 It's a typo - the project IS defined as C++ I'd like to add that NO changes where made to the offending file named: PS_IIC.h It's EXACTLY the same as in the original project. Link to comment Share on other sites More sharing options...
elodg Posted December 18, 2019 Share Posted December 18, 2019 Then it must be another project setting. Do you have "-std=c++11" under g++ compiler/Miscellaneous? Link to comment Share on other sites More sharing options...
bitslip Posted December 18, 2019 Author Share Posted December 18, 2019 This is a snapshot of the settings. Link to comment Share on other sites More sharing options...
elodg Posted December 18, 2019 Share Posted December 18, 2019 I cannot reproduce your error in tag v2018.2-2 of the repo, so I am assuming it has something to do with your modifications. PS_IIC.h is a header file, so the compilation error is actually coming from a module source (.cc) that includes it. The MyCallback shim function is a way to pass and a C++ class member function to a something (XIicPs_SetStatusHandler) that expects a function pointer of type XIicPs_IntrHandler. For this to work you need the shim function to be of the type XIicPs_IntrHandler. Since typedef void (*XIicPs_IntrHandler) (void *CallBackRef, u32 StatusEvent); strictly speaking MyCallback should be of type (note the last argument type): template <typename Func> void MyCallback(void* CallbackRef, u32 i) Try it and see if it works. For me, the function pointer type void (*)(void* CallbackRef, int i) is silently converted to XIicPs_IntrHandler. Link to comment Share on other sites More sharing options...
bitslip Posted December 18, 2019 Author Share Posted December 18, 2019 I did something a little different. I looked at AXI_VDMA.h file and change the contents of PS_IIC.h to be more like it. This is what I did: // I changed the original function prototype : template <typename Func> void MyCallback(void* CallbackRef, int i) { auto pfn = static_cast<std::function<Func>*>(CallbackRef); pfn->operator()(i); } // To this : template <typename Func> void MyCallback(void* CallbackRef, uint32_t mask_or_type) { auto pfn = static_cast<std::function<Func>*>(CallbackRef); pfn->operator()(mask_or_type); } //////////////////////////////////////////////////////////////////////////////////////////////////// // And I changed the original function call : XIicPs_SetStatusHandler (&drv_inst_, &stat_handler_, &MyCallback<void(int)>); // To this : XIicPs_SetStatusHandler (&drv_inst_, &stat_handler_, &MyCallback<void(uint32_t)>); It now compiles well. Can you explain why it didn't work and this solved it ? Link to comment Share on other sites More sharing options...
elodg Posted December 18, 2019 Share Posted December 18, 2019 You should not be modifying the template instantiation &MyCallback<void(int)> to &MyCallback<void(uint32_t)> , because it is incorrect, but it makes the other change actually work. It is subtle, but bear with me. There is a bug in our code, which made the XIicPs_SetStatusHandler call actually use the MyCallback defined in the other header file, AXI_VDMA.h. This happens, because as I explained earlier, XIicPs_SetStatusHandler expects an argument of void (*)(void* CallbackRef, uint32_t i), which is defined in AXI_VDMA.h and not PS_IIC.h. C++ accepts function overloading for MyCallback and calls the one that fits the function prototype. In our project, PS_IIC.h was included after AXI_VDMA.h, so it found a fitting overload. It has the intended behavior but not the intended implementation. So the correct implementation is to have the PS_IIC MyCallback have the same function prototype as the one XIicPs_SetStatusHandler is expecting, void (*) (void *CallBackRef, u32 StatusEvent). But since MyCallbacks are global functions, we get a re-definition error. I think the correct way to do this is to move the callback into the class as static member functions so there is no conflict. Now, on to the other change. MyCallback is a template function executing a functor (std::function) that wraps a member function of an object. MyCallback has a C interface towards XIicPs_SetStatusHandler, and the functor makes the adaptation to the C++ member function. The functor is a member variable of the PS_IIC class under the name stat_handler_. Depending on the prototype of the member function you want to call, the std::function<> needs to be template instantiated with the right type. This type is the void(int) and is the type of void StatusHandler(int Event). This stat_handler_ is initialized in the ctor and bound to the member function it wraps. It is then passed to the XIicPs_SetStatusHandler as a void*. MyCallback casts this void* CallbackRef back to the std::function<> type and calls into it. Phew, that was a lot. I will do a commit with the fix. Link to comment Share on other sites More sharing options...
bitslip Posted December 18, 2019 Author Share Posted December 18, 2019 Thanks! This post of the same project also awaits your kind attention: Link to comment Share on other sites More sharing options...
Question
bitslip
Hello,
While trying to compile (a modified version of) the 18.2 Zybo PCAM 5 demo inside the SDK I got the following error:
no matches converting function 'MyCallback' to type 'XIicPs_IntrHandler {aka void (*)(void*, long unsigned int)}'
The error pointed to the following line of code in a file named PS_IIC.h :
Please explain this error.
Notes:
1. The Vivado project compiled correctly and the hardware was exported successfully to the SDK.
2. The PS_IIC.h file and a snapshot of the error message are attached.
PS_IIC.h
Link to comment
Share on other sites
10 answers to this question
Recommended Posts
Archived
This topic is now archived and is closed to further replies.