What is the use of callback using function pointer when it can be done in a normal way? - callback

I am new to programming. I was not able to understand the use of call back by function pointer clearly. Please help me to understand where actually the function pointers are needed. I have given two examples. One callback using function pointer and other the normal way(Function calling a function). Forgive me if it appears silly.
#include<stdio.h>
void A()
{
printf("Hello");
}
void B(void(*ptr)())
{
ptr();
}
int main
{
void (*p)() = A;
B(p);
}
Another method
#include<stdio.h>
void A()
{
printf("Hello");
}
void B()
{
A();
}
int main
{
B();
}
What is the use of callback using function pointer when this can be achieved in a simpler way?

Related

Flutter, Dart. Create anonymous class

Maybe it's really dumb question. But I cannot believe there is no resources, where it's described. Even from the official documentation. What I'm trying to do, it's create Anonymous class for the next function.
How to create Anonymous class in Dart with custom function something like next in Kotlin?
Handler(Looper.getMainLooper()).post(Runnable() {
#override
open fun run() {
//...
}
private fun local() {
//....
}
})
Dart does not support creating an anonymous class.
What you're trying to do is not possible.
On the other hand, you can create anonymous functions. So you could use that to mimic an anonymous class.
The idea is to add a constructor of your abstract class, that defer its implementation to callbacks.
abstract class Event {
void run();
}
class _AnonymousEvent implements Event {
_AnonymousEvent({void run()}): _run = run;
final void Function() _run;
#override
void run() => _run();
}
Event createAnonymousEvent() {
return _AnonymousEvent(
run: () => print('run'),
);
}
It's not strictly the same as an anonymous class and is closer to the decorator pattern. But it should cover most use-cases.
This is an alternative way, but not fully equivalent:
Problem, e.g.:
I would like to implement OnChildClickListener inline in my code without class. For this method:
void setOnChildClickListener(OnChildClickListener listener) {
...
}
Instead of this:
abstract class OnChildClickListener {
bool onChildClick(int groupPosition, int childPosition);
}
use this:
typedef OnChildClickListener = Function(int groupPosition, int childPosition);
And in code you can implement it in this way:
listView.setOnChildClickListener((int groupPosition, int childPosition) {
// your code here
});
In other words do not use abstract class, but use typedef.

Calling a method in other methods class, multiple times

How to optimize calling a method within other method's class?
I have a method in a class called e.g. print. and I want it to call it in most other's method in the class.
something is fishy about calling a method again and again.
How to avoid forgetting calling that method?
I am totally sure I learned a solution for that before. but I don't remember it right now. Most questions and pages that I found were irrelevant.
hope the way I titled this question, help others!
class Printer() {
public void print() {
// print somthing...
}
public void func1() {
// do some stuff...
// ..
print()
}
public void func2() {
// ...
// do some stuff...
// ..
print()
}
public void func3() {
// ...
}
public void func2() {
// ...
print()
// ...
}
}
I'm not sure about inheritance and overriding method here...
you can re-use using Static methods in a class
public static class Utils
{
public static void Print()
{
//...
}
}
or you can use Extensions in like for example for a string
public static void PrintString(this string str)
{
// your code ... return new string
}
and use it like this
"my text".PrintString()

Static and non-static method or global class object

I'm making a Windows Forms Application in VS2012 C++.
Situation just for example, real project is more complicated:
I have a Form that contains TextBox, Button and Timer.
Button just triggers the timer. Timer just calls function that increments some variable.
I need to display the function's variable that is incremented, in TextBox.
In Form1.h I add code:
public: void Timer_Function(); //function activated by timer Tick
void Set_Text(String ^str); //function to set TextBox Text
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
if (timer1->Enabled == false) timer1->Enabled = true;
else timer1->Enabled = false;
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
Timer_Function();
}
In My_app.cpp code like this:
#include "stdafx.h"
#include "Form1.h"
#include "resource.h"
using namespace test_staticfunc;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew Form1());
return 0;
}
void Form1::Timer_Function()
{
Timer_Func();
}
void Form1::Set_Text(String ^str)
{
textBox1->Text = str;
}
void Timer_Func()
{
static int I=0;
I++;
Form1::Set_Text(I.ToString());
}
Function Timer_Func() is specified in "resource.h" like this:
void Timer_Func();
I.e. I'm trying to display the current state of inner variable I of Timer_Func() by passing it to a Form1 public method Set_Text().
So. The error here is that Set_Text() is not a static method.
I tried to make it static, but got an error "С2227: The operand to the left of "->Text" is not a pointer to a class, structure, or union." How to get it right? In that case a static method is trying to implement a non-static method, right?
Or another way: to make an instance of Form1 - instead of
Application::Run(gcnew Form1());
insert code
Form1 ^My_form = gcnew Form1();
Application::Run(My_form);
And use Set_Text as non-static method for class instance My_form.
But My_form is available only in main()! I couldn't make My_form anywhere else. Is there way to make it global or something?
May be there are other ways to solve this problem?
Help, please! I've already searched several forums for answer but didn't find the answer. More precisely non of them suited.
P.S. Sorry for my bad english! ^_^

How to call java method from javascript method that located within another jsni method

public class A{
private void javaMethod(int a,int b){}
private native void init()/*-{
function OnMouseMove(e) {
//blow calling doesn't work
this.#p::javaMethod(Ljava/...teger;Ljava.../Integer;)(intVal,intVal);
}
}-*/;
}
As described above,how to make that invoking work?
Answered on the Google Group: https://groups.google.com/d/msg/google-web-toolkit/qE2-L4u_t4s/YqjOu-bUfsAJ
Copied here for reference and convenience:
First, int is not java.lang.Integer, so your method signature in JSNI is wrong; it should read javaMethod(II).
(I suppose the #p:: while javaMethod is defined in class A is over-simplification in your question, but is OK in your code)
You'll also probably have a problem with this, that might not be what you think it is. A common pattern is to assign the current object (this, at the time) to a variable that you'll reference from your closure:
var that = this;
…
function OnMouseMove(e) {
that.#p.A::javaMethod(II)(intVal, intVal);
}
You're doing two things wrong:
You're not defining the class name after #p, (assuming #p is actually just a shortened version of the real package's name);
You're attempting to pass java.lang.Integer in place of int. You should be saying (II) as the types, as described here.
Your code should look more like this:
package com.my.package;
public class ClassA {
private static void javaMethod(int a, int b) { ... }
public static native void init() /*-{
$wnd.javaMethod = function(a, b) {
return #com.my.package.ClassA::javaMethod(II)(a,b);
}
function OnMouseMove(e) {
$wnd.javaMethod(a,b);
}
}-*/;
}

C++/CLI class wrapper for c library - callbacks

I am wrapping a C library using C++/CLI. The C library was designed to be used from an unmanaged C++ class. This means that the library functions accept a C++ object pointer and then provide that pointer back in callbacks. This enables the callback code to redirect requests to an appropriate event function in the calling C++ object.
The actual functions are quite involved, so I have simplified the problem space to just a few basic items:
// C library function signature
void CLibFunc(CLIBCALLBACK *callback, void *caller);
// C callback signature
// Second parameter is meant to point to the calling C++ object
typedef int (__stdcall CLIBCALLBACK) (int param1, void *caller);
// C callback implementation
int CallBackImpl(int param1, void* caller)
{
// Need to call the ManagedCaller's EventFunction from here
// ???
}
// C++/CLI caller class
public ref class ManagedCaller
{
public:
void CallerFunction(void)
{
// Call the C library function
// Need to pass some kind of this class pointer that refers to this object
CLibFunc(CallBackImpl, ????);
}
void EventFunction(param1)
{
}
}
Now the C library functions need to be called from a managed C++ class. Under C++/CLI, the garbage collector moves objects around in memory, so passing a simple fixed pointer to the class does not work anymore. I can solve the problem by pinning the object, but that is not recommended because it leads to memory fragmentation. It seems that another option would be to use auto_gcroot pointers, but I am fairly new to managed C++ an I am not sure how to make this work.
Does anyone know how to make this work? What kind of pointer should be passed to the C function? How should the callback implementation redirect to the calling object's event function?
This just happens to be similar to something I'm in the middle of working on right now.
Here is an blog post on providing native callbacks using C++ classes: http://blogs.microsoft.co.il/blogs/alon/archive/2007/05/29/Native-Callback.aspx
I'm not familiar with calling C++ member functions from C, but I have done an interface (abstract base) class to another C++ class for callbacks (similar to the article). Here is a basic example of what I am providing a bridge for:
// Interface (abstract base) class providing the callback
class IProvider {
public:
virtual ~IProvider() {}
virtual void Callback() = 0;
};
// User class of the callback
class CUser {
IProvider * m_pProvider;
public:
CUser(IProvider * pProvider) {
m_pProvider = pProvider;
}
void DoSomething() {
m_pProvider->Callback();
}
};
// Implementation of the interface class
class CHelloWorldProvider : public IProvider {
void Callback() {
printf("Hello World!");
}
};
// Usage of the callback provider in a pure native setting
void PureNativeUsage() {
CHelloWorldProvider oProvider;
CUser oUser(&oProvider);
oUser.DoSomething();
}
Now in order to make this available for managed implementations of the provider, we have to create a series of classes that provide the bridge.
// Where gcroot is defined
#include <vcclr.h>
// Managed provider interface class
public interface class IManagedProvider {
void Callback();
};
// Native bridge class that can be passed to the user
class CProviderBridge : public IProvider {
// Give the managed class full access
friend ref class ManagedProviderBase;
// Store a reference to the managed object for callback redirects
gcroot<IManagedProvider ^> m_rManaged;
public:
void Callback(){
m_rManaged->Callback();
}
};
// Managed provider base class, this provides a managed base class for extending
public ref class ManagedProviderBase abstract : public IManagedProvider {
// Pointer to the native bridge object
CProviderBridge * m_pNative;
protected:
ManagedProviderBase() {
// Create the native bridge object and set the managed reference
m_pNative = new CProviderBridge();
m_pNative->m_rManaged = this;
}
public:
~ManagedProviderBase() {
delete m_pNative;
}
// Returns a pointer to the native provider object
IProvider * GetProvider() {
return m_pNative;
}
// Makes the deriving class implement the function
virtual void Callback() = 0;
};
// Pure managed provider implementation (this could also be declared in another library and/or in C#/VB.net)
public ref class ManagedHelloWorldProvider : public ManagedProviderBase {
public:
virtual void Callback() override {
Console::Write("Hello World");
}
};
// Usage of the managed provider from the native user
void MixedUsage() {
ManagedHelloWorldProvider ^ rManagedProvider = gcnew ManagedHelloWorldProvider;
CUser oUser(rManagedProvider->GetProvider());
oUser.DoSomething();
}
Edit: Added code to show w/o the managed interface class example I use.
Here is a modified version of my example that can be used given your CLibFunc above. This is assuming how the C function performs the callback is accurate.
Also this might be able to be slimmed down a bit depending on how involved your callback classes are and how much freedom for extension you need.
// Where gcroot is defined
#include <vcclr.h>
// C callback signature
// Second parameter is meant to point to the calling C++ object
typedef int (__stdcall CLIBCALLBACK) (int param1, void *caller);
// C library function
void CLibFunc(CLIBCALLBACK *callback, void *caller) {
// Do some work
(*callback)(1234, caller);
// Do more work
}
// Managed caller interface class
public interface class IManagedCaller {
void EventFunction(int param1);
};
// C++ native bridge struct
struct CCallerBridge {
// Give the managed class full access
friend ref class ManagedCaller;
// Store a reference to the managed object for callback redirects
gcroot<IManagedCaller ^> m_rManaged;
public:
// Cast the caller to the native bridge and call managed event function
// Note: This must be __stdcall to prevent function call stack corruption
static int __stdcall CallBackImpl(int param1, void * caller) {
CCallerBridge * pCaller = (CCallerBridge *) caller;
pCaller->m_rManaged->EventFunction(param1);
return 0;
}
};
// C++/CLI caller class
public ref class ManagedCaller : public IManagedCaller {
// Pointer to the native bridge object
CCallerBridge * m_pNative;
public:
ManagedCaller() {
// Create the native bridge object and set the managed reference
m_pNative = new CCallerBridge();
m_pNative->m_rManaged = this;
}
~ManagedCaller() {
delete m_pNative;
}
// Calls the C library function
void CallerFunction() {
CLibFunc(CCallerBridge::CallBackImpl, m_pNative);
}
// Managed callback function
virtual void EventFunction(int param1) {
Console::WriteLine(param1);
}
};
// Usage
int main(array<System::String ^> ^args) {
ManagedCaller ^ oCaller = gcnew ManagedCaller();
oCaller->CallerFunction();
return 0;
}