如何将带有固定参数的函数传递给C中的另一个方法? [英] How do I pass a function with a fixed parameter to another method in C?

查看:92
本文介绍了如何将带有固定参数的函数传递给C中的另一个方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个print方法,它将void *作为参数:



Suppose I have a print Method which takes a void* as an argument:

Print(void *instance)





如何将结构的成员设置为此方法?





How can I Set the member of a struct to this method?

struct Foo
    {
        void(*Print)(); //this does not match to Print above!
       //void(*Print)(void* Instance); //This would but I cannot change this
    }





那么我该怎么做才能改变这个方法:



So how would I have to change this method:

void Init()
{
   struct Foo* k = malloc(sizeof(Foo));

   Foo->Print = &Print(k);   //does not work!
 //Foo->Pring = &Print;     //would work if types were the same and I really need the parameter k there.
    }





我想设置一个带 Fixed Argument 的函数指针。

这将是为此项目在ANSI C中做出真正的对象行为:

C中的面向对象?



String * r = New_String(Hello);

r->免费(r);

应该成为r->免费();



谢谢提前



我尝试过:



其他语言会支持它像这样:



Foo.Print =()=>打印(k);



必须在运行时插入参数。

任何非标准的疯狂方式都值得赞赏。



例如从方法中查找Foo结构实例用来调用Foo-> Print();



I want to set a function pointer with a Fixed Argument.
This would be to make truly object like behaviour in ANSI C for this Project:
Object Orientation in C?!

String* r = New_String("Hello");
r->Free(r);
Should become r->Free();

Thanks in advance

What I have tried:

Other languages would support it like this:

Foo.Print = ()=>Print(k);

The argument has to be inserted at runtime.
Any non standard crazy ways are appreciated.

For example finding the Foo struct instance from the method which was used to call Foo->Print();

推荐答案

函数签名必须匹配,否则你可以有类似的东西:

The function signature must match, otherwise you could have something like:
void Print(void* pp)
{
	// do stuff
}
void Print(char* cp, int i)
{
	// do stuff
}

//

struct Foo
{
    void(*Print)(); // so which one does the compiler choose?
}


在C语言中没有简单的方法。当然,您可以编写汇编代码来动态创建具有指定参数的函数(假设您可以在开发中编写此类代码)环境)。



另一方面,你可能并不真的需要它。通常,你的struct中会有一个静态函数获取实例参数,该函数会调用该实例的成员函数。



目前尚不清楚你是否在编写C语言或C ++代码。如果你编写C代码,那么你还没有成员函数,所以做那种东西是没有意义的。如果你编写C ++代码,那么你应该使用new而不是malloc ...



另外,你想在一个函数指针中设置一个函数指针看起来很奇怪struct指向一个全局函数。



显然,这就是你想要做的,然后它非常简单(假设是C ++):

There are no easy way to do that in C. Of course, you could write assembler code to dynamically create a function with specified argument (assuming you are allowed to write such code in your developing environment).

On the other hand, you probably don't really need that. Usually, you would have a static function taking instance argument in your struct and that function would call member function of that instance.

It is not clear if you are writing C or C++ code. If you write C code, then you don't have member function anyway so it is pointless to do that kind of stuff. If you write C++ code, then you should have used new instead of malloc anyway...

Also, it look weird that you want to set a function pointer in a struct point to a global function.

Obviously, it that is what you want to do, then it is extremely simple (assuming C++):
struct Foo
{
    void(*Print)(void* Instance);
    void PrintMe() { (*Print)(this); }
};



如果你真的想要另一种方式,那么你将有一个静态成员获取一个可被解释为实例的参数:


If you really want to it the other way, then you would have a static member taking a parameter that would be interpreted as an instance:

struct Foo2
{
    static void PrintFuction(void *instance) 
    { 
        reinterpret_cast<foo2>(instance)->PrintMember();
    }
    static void PrintMember() { /* code here */ }
};





顺便说一下,在C#等其他语言中,编译器本质上会生成一个包含其成员数据的类。这样的函数将由一对{function,instance}表示。



另外,在现代C ++中你也有这样的函数对象。



因此,目前还不清楚你想用它做什么,它可能不是最好的方法...特别是如果你有权访问整个代码。



- 更新(2016-10-07) -



如评论中所示,仅使用标准C无法实现所需的语法。



对于内存访问回调,我不知道关于那个。我找到了以下信息: http://stackoverflow.com/questions/6211429/callback-on -memory-access / 6211502 [ ^ ]。



我可以说它是一个特定的Linux功能。并且为了简化语法而使用它,必须确保他使用正确的调用约定,任何使用过的编译器优化都与hack兼容,并且他永远不想将代码移植到任何其他平台这样的黑客可能是不可能的。



基本上,黑客就是在某些特定情况下,您可能知道哪个寄存器或相对堆栈位置是功能刚刚调用。根据该信息,您可以计算this的地址并进行必要的调整,以便函数查看正确的信息。



即便如此,黑客攻击可能会给你带来调试,错误处理或兼容性问题。



这不是应该用于常规开发的东西,或者只是为了方便更好句法。如果这是你想要的,那么你应该认真考虑一个C ++编译器。



如果为特定平台开发一些特定的库,那么这种hack可能会有用像RTOS,分析器,堆栈跟踪分析器......但如果你编写了这样的工具,那么你需要深入了解你的平台和编译器。



< b>认真地......使用C ++编译器!



在大多数情况下做这种黑客行为是没有意义的,特别是如果唯一的目的是拥有更好的语法。



显然,有很多理由可能会导致它不值得努力。实际上,如果您的应用程序崩溃或之后的行为不正确,您不知道问题是否是由黑客引起的,并且没有简单的方法来测试它,因为您必须还原所做的所有更改以改进代码。 br />


替代



您可以使用能够生成的C ++编译器C代码。请参阅 http://stackoverflow.com/questions/3311563/do-all-c -compilers-generate-c-code [ ^ ]了解更多信息。



By the way, in other language as C#, the compiler would essentially generate a class with the data in the members of it. And such function would be represented by a pair of {function, instance}.

Also, in modern C++ you also have such function object.

Thus it is not clear what you are trying to achieve with that and it might not be the best way to do it... in particular if you have access to the whole code.

— Update (2016-10-07)—

As indicated in comments, it is not possible to achieve desired syntax using only standard C.

For "Memory access callback", I didn't know about that. I have found the following information: http://stackoverflow.com/questions/6211429/callback-on-memory-access/6211502[^].

The thing I can say it that it is a specific Linux function. And to use it for the purpose of simplifying the syntax, one would have to ensure that he use the proper calling convention, that any used compiler optimization are compatible with the hack and that he would never want to port the code to any other platform where such hack might not be possible.

Essentially, the hack would be that in some specific cases, you might know in which register or relative stack location is the address of the function just called. From that information, you might be able to compute the address of "this" and make any necessary adjustment so that the function see the correct information.

And even then, that hacking might give you problems with debugging, error handling or compatibility issues.

This is not something that should be used for regular development or just for the convenience of a nicer syntax. If this is what you want, then you should seriously consider a C++ compiler.

That kind of hack might be useful if one develop some specific library for a specific platform for things like RTOS, profilers, stack trace analysers... But if you wrote such tools, then you need to have a deep understanding of your platform and compiler.

Seriously... uses a C++ compiler!

It does not make sense to do that kind of hack in most cases and in particular if the only purpose is to have a nicer syntax.

Obviously, there are so many reason why it might break that it won't worth the effort. In fact, if you application crash or does not behave correctly afterwards, you have no idea if the problem is caused by the hack and no easy way to test it since you would have to revert all the changes you made to improve the code.

Alternative

You can use a C++ compiler that is able to generate C code. See http://stackoverflow.com/questions/3311563/do-all-c-compilers-generate-c-code[^] for more information.


这篇关于如何将带有固定参数的函数传递给C中的另一个方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆