Getting an error on a qsort compare function - c++builder

I'm using C++Builder 10.4.2 and having a problem with qsort. I rarely use qsort so I might be making a clumsy mistake. Array 'buffer' is a 2D 'char' array with more than 26,000 rows of single words.
This is the call:
qsort((void *)buffer,wordcount,sizeof(buffer[1]),sort_function);
This is the compare function:
int TForm::sort_function(const void *a, const void *b)
{
return( strcmp((char *)a,(char *)b) );
}
This is the error message. Notice that it's complaining about sort_function for 4th argument:
search.h(46): candidate function not viable: no known conversion from 'int (__closure *)(const void *, const void *)' to 'int (*)(const void *, const void *) __attribute__((cdecl))'
What is 'int (__closure *)'? Is there a way to fix my compare function?

__closure is a Borland compiler extension for obtaining a pointer to a non-static class method, without regard to the type of class being used. This is most commonly used in VCL/FMX components, which allow you to assign event handlers from any class you want, which is not something that standard C++ typically allows you to do.
qsort() expects a C-style function pointer in the 4th parameter. You can't get such a pointer to a non-static class method.
To solve this, you need to use either:
a standalone function
a static class method
a non-capturing C++ lambda (C++11 or higher only)
Since your sort_function() does not need access to your TForm object, declaring sort_function() as static would be the simplest fix:
// .h
class TForm
{
...
private:
static int sort_function(const void *a, const void *b);
void doSomething();
...
};
// .cpp
int TForm::sort_function(const void *a, const void *b)
{
return strcmp((const char *)a, (const char *)b);
}
void TForm::doSomething()
{
...
qsort(buffer, wordcount, sizeof(buffer[1]), sort_function);
...
}
However, it really should be a standalone function instead since it really has no relation to your TForm class at all:
// .cpp
static int sort_function(const void *a, const void *b)
{
return strcmp((const char *)a, (const char *)b);
}
void TForm::doSomething()
{
...
qsort(buffer, wordcount, sizeof(buffer[1]), sort_function);
...
}

Related

store a lambda that captures this

Using C++ 17, I'm looking for a way to store a lambda that captures the this pointer, without using std::function<>. The reason to not using std::function<> is that I need the guaranty that no dynamic memory allocations are used. The purpose of this, is to be able to define some asynchronous program flow. Example:
class foo {
public:
void start() {
timer(1ms, [this](){
set_pin(1,2);
timer(1ms, [this](){
set_pin(2,1);
}
}
}
private:
template < class Timeout, class Callback >
void timer( Timeout to, Callback&& cb ) {
cb_ = cb;
// setup timer and call cb_ one timeout reached
...
}
??? cb_;
};
Edit: Maybe it's not really clear: std::function<void()> would do the job, but I need / like to have the guaranty, that no dynamic allocations happens as the project is in the embedded field. In practice std::function<void()> seems to not require dynamic memory allocation, if the lambda just captures this. I guess this is due to some small object optimizations, but I would like to not rely on that.
You can write your own function_lite to store the lambda, then you can use static_assert to check the size and alignment requirements are satisfied:
#include <cstddef>
#include <new>
#include <type_traits>
class function_lite {
static constexpr unsigned buffer_size = 16;
using trampoline_type = void (function_lite::*)() const;
trampoline_type trampoline;
trampoline_type cleanup;
alignas(std::max_align_t) char buffer[buffer_size];
template <typename T>
void trampoline_func() const {
auto const obj =
std::launder(static_cast<const T*>(static_cast<const void*>(buffer)));
(*obj)();
}
template <typename T>
void cleanup_func() const {
auto const obj =
std::launder(static_cast<const T*>(static_cast<const void*>(buffer)));
obj->~T();
}
public:
template <typename T>
function_lite(T t)
: trampoline(&function_lite::trampoline_func<T>),
cleanup(&function_lite::cleanup_func<T>) {
static_assert(sizeof(T) <= buffer_size);
static_assert(alignof(T) <= alignof(std::max_align_t));
new (static_cast<void*>(buffer)) T(t);
}
~function_lite() { (this->*cleanup)(); }
function_lite(function_lite const&) = delete;
function_lite& operator=(function_lite const&) = delete;
void operator()() const { (this->*trampoline)(); }
};
int main() {
int x = 0;
function_lite f([x] {});
}
Note: this is not copyable; to add copy or move semantics you will need to add new members like trampoline and cleanup which can properly copy the stored object.
There is no drop in replacement in the language or the standard library.
Every lambda is a unique type in the typesystem. Technically you may have a lambda as a member, but then its type is fixed. You may not assign other lambdas to it.
If you really want to have an owning function wrapper like std::function, you need to write your own. Actually you want a std::function with a big enough small-buffer-optimization buffer.
Another approach would be to omit the this capture and pass it to the function when doing the call. So you have a captureless lambda, which is convertible to a function pointer which you can easily store. I would take this route and adapter complexer ways if really nessessary.
it would look like this (i trimmed down the code a bit):
class foo
{
public:
void start()
{
timer(1, [](foo* instance)
{
instance->set_pin(1,2);
});
}
private:
template < class Timeout, class Callback >
void timer( Timeout to, Callback&& cb )
{
cb_ = cb;
cb_(this); // call the callback like this
}
void set_pin(int, int)
{
std::cout << "pin set\n";
}
void(*cb_)(foo*);
};

Variadic Dispatch Function

I have an interface wherein the types of the parameters mostly encode their own meanings. I have a function that takes one of these parameters. I'm trying to make a function that takes a set of these parameters and performs the function on each one in order.
#include <iostream>
#include <vector>
enum param_type{typeA,typeB};
template <param_type PT> struct Container{
int value;
Container(int v):value(v){}
};
int f(Container<typeA> param){
std::cout<<"Got typeA with value "<<param.value<<std::endl;
return param.value;
}
int f(Container<typeB> param){
std::cout<<"Got typeB with value "<<param.value<<std::endl;
return param.value;
}
My current solution uses a recursive variadic template to delegate the work.
void g(){}
template <typename T,typename...R>
void g(T param,R...rest){
f(param);
g(rest...);
}
I would like to use a packed parameter expansion, but I can't seem to get that to work without also using the return values. (In my particular case the functions are void.)
template <typename...T> // TODO: Use concepts once they exist.
void h(T... params){
// f(params);...
// f(params)...; // Fail to compile.
// {f(params)...};
std::vector<int> v={f(params)...}; // Works
}
Example usage
int main(){
auto a=Container<typeA>(5);
auto b=Container<typeB>(10);
g(a,b);
h(a,b);
return 0;
}
Is there an elegant syntax for this expansion in C++?
In C++17: use a fold expression with the comma operator.
template <typename... Args>
void g(Args... args)
{
((void)f(args), ...);
}
Before C++17: comma with 0 and then expand into the braced initializer list of an int array. The extra 0 is there to ensure that a zero-sized array is not created.
template <typename... Args>
void g(Args... args)
{
int arr[] {0, ((void)f(args), 0)...};
(void)arr; // suppress unused variable warning
}
In both cases, the function call expression is cast to void to avoid accidentally invoking a user-defined operator,.

C++Builder Console application: linking to a __closure based method

First off, forgive me on the title. Not really sure how to ask this question:
I have an application that I need to convert to a console application (note the application runs fine as a VCL style windows app). The app uses a few 3rd party widgets that have callback functions. However, when I attempt to compile it, I get 'cannot convert ...' errors, like this:
Cannot convert 'void(Tobject *, TErrorEventParams *)' to 'TErrorEvent'
TErrorEvent is defined as:
typedef void __fastcall (__closure* TErrorEvent)(System::TObject* Sender, TErrorEventParams *e);
The line causing the error is:
handler->OnError = errorHandler;
The code for errorHandler is:
void __fastcall errorHandler(System::TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
A __closure type is a pointer to a non-static class method. The compiler does not allow you to assign a standalone non-class function where a __closure is expected. It requires a pointer to a method of a class object. Karem's answer shows you one way to accomplish that.
However, there IS a way to use a non-class function, using the helper TMethod struct (which is how a __closure is implemented behind the scenes).
First, add an explicit 'this' parameter to your event handler:
void __fastcall errorHandler(void *This, TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
And then assign the event handler like this:
TMethod m;
m.Code = &errorHandler
m.Data = NULL; // any value you want to pass to the 'This' parameter...
handler->OnError = reinterpret_cast<TErrorEvent&>(m);
Have a look at this documentation:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Closure
In short:
TErrorEvent is defined as a pointer to a class member function. So errorHandler has to be declared as a class member function.
The implementation could look somewhat like this:
class TMyClass
{
private:
TMyHandler* handler;
void __fastcall errorHandler(System::TObject* Sender, TErrorEventParams *e);
public:
__fastcall TMyClass();
} my_dummy_class;
__fastcall TMyClass::MyClass()
{
//handler has to be created
handler->OnError = errorHandler;
}
void __fastcall TMyClass::errorHandler(System::TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}

iOS UnitySendMessage call parameter

I am writing the Objective-C part of a Unity project. In AppController.mm, I declared
extern void UnitySendMessage(const char *, const char *, const char *);
And I am calling this like,
- (void)callUnityObject:(const char*)object Method:(const char*)method Parameter:(const char*)parameter
{
UnitySendMessage(object, method, parameter);
}
But I have a Unity function that has to receive an int parameter.
So, if I call like this:
[self callUnityObject:"_iosManager" Method:"GiveDynamite" Parameter:"50"];
The app doesn't crash, but the call doesn't work and I am getting an output like this:
The best match for method GiveDynamite has some invalid parameter.
If I call like this:
[self callUnityObject:"_iosManager" Method:"GiveDynamite" Parameter:50];
The App is crashing.
How can I send this message from Objective-c to Unity?
I tried declaring a new method like this:
extern void UnitySendMessage(const char *, const char *, int);
But the app crashed and said that unity doesn't have a function declaration like that.
Thanks in advance.
According to:
void UnitySendMessage( const char * className, const char * methodName, const char * param )
You should pass char*:
[self callUnityObject:"_iosManager" Method:"GiveDynamite" Parameter:"50"];
On Unity class you should receive "string" param
void GiveDynamite(string dinamite) {
...
}
and then parse it to integer value, f.e:
dinamiteAmount = int.Parse(dinamite);

creating checkbox/button in opencv

The error while creating a button in opencv
argument of type 'void (Window::)(int, void*)' does not match 'cv::ButtonCallback {aka void ()(int, void)}'
class Window{
void ChecKBox(int state, void* val){
// do nothing for now
return;
}
public:
void createCheckbox(){
cv::createButton(checkboxname, CheckBox, NULL, CV_CHECKBOX, 0);
}
};
int main(){
Window w;
w.createCheckBox();
}
I can't seem to find the fix to this problem.
oh, you can't pass in a member function of a class here. think of it, where would the 'this' pointer come from ? (like you call class members like w.CheckBox(1,NULL); there is no 'w' here. )
the highgui interface is a bit limited. it can only call free functions or static members.
so, if your callback function does not need anything from Window, make it static:
class Window {
static void CheckBox(int state, void* val) { /*you can't use 'this' here!*/ return; }
public:
void createCheckBox() { cv::createButton(checkboxname, CheckBox, NULL, CV_CHECKBOX, 0); }
};
int main() {
Window w;
w.createCheckBox();
}

Resources