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

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
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.

I updated the OP again I apologies for the badly formulated question before.
Cheers!
Last edited on
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
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
Topic archived. No new replies allowed.