How to pass the address of C + + member function to C__jquery

Source: Internet
Author: User

[CSDN] Original

Accidentally try to a C + + member function to the address of the method, can cheat the compiler, but Run-time stack error, not much practical significance, recorded here, the right to be a pastime.


Typically, the address of a member function in C + + cannot be passed to C unless it is a static member function. Because the normal member function has an implied this pointer, which is not in C, if you call each other with C, it can cause stack clutter error due to incompatible maintenance between the two sides of the parameters and the stack. If you pass the normal member function address to C, the compiler will make an error.

For example, there is a function CFun01 in C that requires a callback function pointer as an argument:

. c
int CFunc01 (int (*CB) (int))
{return
	CB (0X55AA);
}

Define a function in the C + + class and pass it to C:

. cpp
class C
{public
:
	int Fun01 (int a)
	{
		printf ("c::fun01:a = 0x%x\n", a);
		return 0;
	}

	int Fun02 (int a)
	{
		CFunc01 (&c::fun01);
		return 0;
	}
;

The compiler will report an error at FUN02:

Error C2664: ' CFUNC01 ': cannot convert parameter 1 from ' Int (__thiscall C::*) (int) ' to ' int (__cdecl *) (int) '
There is no context in which this conversion is possible


The following methods can be used to trick the compiler into forcing the member function address to be passed to C:

. cpp
#include "stdarg.h"

int getfuncaddr (int t, ...)
{
	va_list va;
	Va_start (VA, t);
	int addr = va_arg (va, int);
	return addr;
}

extern "C" int CFunc01 (int (*) (int));

Class C
{public
:
	int Fun01 (int a)
	{
		printf ("c::fun01:a = 0x%x\n", a);
		return 0;
	}

	int Fun02 (int a)
	{
		CFunc01 (int (*) (int)) getfuncaddr (0, &c::fun01));
		return 0;
	}
;

In getfuncaddr, using the characteristics of indefinite parameters, let the compiler put the function address on the stack, and then remove the function address from the stack as an integer, thus bypassing the compiler type check, very magical feeling.

The above methods in the VS2005 test through, if it is VC6, the "&c::fun01" replaced by "Fun01" can be.


However, although bypassing the compiler, but not through the actual CPU to run, in the actual operation, C::fun01 can be called back to, but the function finished return after the stack chaos.

Run Result:

C::fun01:a = 0X55AA

The run result is correct, but there are error prompts after running:

Run-time Check Failure #0-the value of ESP is not properly saved across a function call. This is usually a result of the calling a function declared with one calling convention with a function pointer declared with A different calling convention.

Obviously, because of the inconsistent pressure stack rules of function parameters, the stack clutter is caused.


So the above methods can only be used as a pastime, and ultimately can only use the traditional static members of the method, helpless:

The traditional method is written below as an end.

. c
int CFunc01 (int (*CB) (void *, int), void *context)
{return
	CB (context, 0X55AA);
}

. cpp
extern "C" int CFunc01 (int (*) (void *, int));

Class C
{
private:
	int Fun01 (int a)
	{
		printf ("c::fun01:a = 0x%x\n", a);
		return 0;
	}

	static int __fun01 (void *context, int a);

Public:
	int Fun02 (int a)
	{
		CFunc01 (__fun01);
		return 0;
	}
;

int C::__fun01 (void *context, int a)
{return
	((C *) context)->fun01 (a);
}

int _tmain (int argc, _tchar* argv[])
{
	c C;
	Return c.fun02 (0);
}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.