How to pass function pointer of a class method as C pointer?

Jun 25, 2017 at 5:12pm
Post Edited:

Apologies for the badly formulated question.

Here is a use example.

In my class am drawing UI using ImGui::https://github.com/ocornut/imgui

The function takes a function pointer.
1
2
3
typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);

bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data)


Now i can use a static member function in my class and it will compile fine.
But this don`t give me access to members of the class.

So i tried everything i could think of lastly lambda functions like this.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class MyConsoleWindow :
	public MyUIWindow
{
public:
	MyConsoleWindow();
	~MyConsoleWindow();

	int DoSomething();

	char *sExecCommand;
	char *sConsoleBuf;

	void DrawUIWindow() override;

	ImGuiTextEditCallback testPtr;
	ImGuiTextEditCallbackData* userData;

	int(*test)(ImGuiTextEditCallbackData* testData) = [](ImGuiTextEditCallbackData* testData)
	{
		return 0;
	};

};


void MyConsoleWindow::DrawUIWindow()
{
	ImGui::Begin("Console Window");
	ImGui::SetWindowSize(ImVec2(520, 600));
	ImGui::Separator();

	ImGui::BeginChild("Console", ImVec2(500, 540), true, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_ShowBorders);
	ImGui::Text(sConsoleBuf);
	ImGui::EndChild();

	ImGui::Separator(); 

	ImGui::InputText("Exec", sExecCommand, IM_ARRAYSIZE(sExecCommand), ImGuiInputTextFlags_EnterReturnsTrue, test);

	if (ImGui::IsItemHovered() || (ImGui::IsRootWindowOrAnyChildFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)))
		ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget

	ImGui::End();
}


This will compile but there are 2 problems here.
Like this code never seem to be run nothing is printed to debug console. (code removed for space)

Secondly if i pass in reference like this.
1
2
3
4
5
	int(*test)(ImGuiTextEditCallbackData* testData) = [&](ImGuiTextEditCallbackData* testData)
	{
		userData = testData;
		return 0;
	};


I get the following errors.

1>f:\path\d3d11hook\MyConsoleWindow.h(304) : error C2440 : 'initializing' : cannot convert from 'MyConsoleWindow::<lambda_ea6abeb6dbe475b4705e8a99f99a9a79>' to 'int (__cdecl *)(ImGuiTextEditCallbackData *)'
1>f:\path\MyConsoleWindow.h(304) : note: No user - defined - conversion operator available that can perform this conversion, or the operator cannot be called
1>f:\pathMyConsoleWindow.h(304) : error C2439 : 'MyConsoleWindow::test' : member could not be initialized
1>f:\path\MyConsoleWindow.h(300) : note: see declaration of 'MyConsoleWindow::test'


I have no idea how to solve this issue, especially since i just picked up Lambda`s.
Thanks for any help.
Last edited on Jun 27, 2017 at 1:26am
Jun 26, 2017 at 2:31pm
Not totally following your question.

classes can have static data elements or static functions, either or both.

are you asking for syntax example of this? It works fine. If you make a static data element, like bool show, if you change it in one instance of the class, you change it for all ... its shared effectively.

Jun 27, 2017 at 1:16am
I updated the OP again I apologies for the badly formulated question before.
Cheers!
Last edited on Jun 27, 2017 at 1:27am
Jun 27, 2017 at 3:40am
A lambda can only be converted to the corresponding function-pointer type if its capture-list is empty. Remember that the type of a lambda expression is exactly an (anonymous) class: your attempt simply moves the problem elsewhere (into the resultant ClosureType).

There is a void* parameter available for this purpose. Pass the callback a handle to the appropriate member function, or the data you need.
Last edited on Jun 27, 2017 at 3:43am
Jun 27, 2017 at 2:47pm
A lambda can only be converted to the corresponding function-pointer type if its capture-list is empty.
… or by using std::function for capturing lambda's:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# include <iostream>
# include <functional>

void printLambda(std::function<int ( )> captureLambda)
{
    std::cout << captureLambda () << "\n";
}

int main()
{
    int num = 42;

    std::function<int()> captureLambda = [&](){return num * num; };
   //auto captureLambda = [&](){return num * num; };
    printLambda(captureLambda);
}
Last edited on Jun 27, 2017 at 2:54pm
Topic archived. No new replies allowed.