出于好奇,我试图了解C中函数的指针是如何工作的。
为了将一个函数与一个typedef相关联,我在其中定义了一个指针,然后在其中存储了所需函数的地址。
这是我能够实现的:
typedef struct
{
void (*get)(char*, int);
char string[10];
} password;
int main()
{
password userPassword;
userPassword.get = &hiddenStringInput;
userPassword.get(userPassword.string, 10);
return EXIT_SUCCESS;
}
尽管这确实可以正常工作,但我希望“ userPassword.get”成为一种快捷方式,在使用该快捷方式时会调用hiddenStringInput函数并填写请求的参数(在这种情况下,是字符数组和整数) 。
基本上,由于我总是将userPassword.get与参数“ userPassword.string”和“ 10”结合使用,因此我试图找到一种方法,以某种方式将这些参数存储在指向到hiddenString函数。甚至有可能吗?
答案 0 :(得分:2)
我通常看到的方式是通过提供“调度”功能:
void get(password * pw) {
pw->get(pw->string, 10);
}
然后,在将userPassword.get
设置为函数后,您只需调用:
get(userPassword);
很显然,完成多种功能后,这会添加一些样板代码。不过,允许实现更多有趣的“类”事物。
答案 1 :(得分:1)
您可以使用“块”语言扩展名在Clang中执行此操作。正如所评论的,there have been attempts to standardize this(并没有收到敌意或其他任何东西),但是他们的行动缓慢。
翻译为使用块,您的示例如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Api1Service>();
services.AddSingleton<Api2Service>();
}
捕获数组的方式有些细微之处,可能会混淆这种情况;该示例通过普通指针捕获了密码,并假定[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{
private readonly Api1Service _api1Service;
private readonly Api2Service _api2Service;
public MyController(Api1Service api1Service, Api2Service api2Service)
{
_api1Service = api1Service;
_api2Service = api2Service;
}
[HttpPost]
public async Task Post([FromBody] string value)
{
var result1 = await apiService1.GetApiResultAsync();
var result2 = await apiService2.GetApiResultAsync();
}
}
与该密码块分开负责#include <stdlib.h>
#include <Block.h>
typedef void (^GetPw)(int); // notice how Block pointer types are used
typedef void (*GetPw_Impl)(char*, int); // the same way as function pointer types
typedef struct
{
GetPw get;
char string[10];
} password;
extern void hiddenStringInput(char*, int);
extern void setPw(char dst [static 10], char * src);
GetPw bindPw (GetPw_Impl get_impl, char * pw)
{
return Block_copy (^ (int key) {
get_impl (pw, key);
});
}
int main()
{
password userPassword;
setPw(userPassword.string, "secret");
userPassword.get = bindPw(hiddenStringInput, userPassword.string);
userPassword.get(10);
return EXIT_SUCCESS;
}
的所有权。
由于块捕获值,因此它需要为捕获的值的副本提供并释放动态存储,这些副本将在将块本身复制到创建范围之外时创建。这是通过userPassword
和Block_copy
函数完成的。
块类型(语法上是函数指针,但使用Block_release
而不是^
)是 just 指针-无法访问基本的块实体,就像基本的C语言一样功能。
这是Clang API-标准化会对此稍作更改,并且可能会减少动态内存分配以在其周围复制块的需求(但Clang API反映了当前最常用的方式)。
答案 2 :(得分:-1)
所以,我刚刚意识到我可以直接在结构内部编写函数
typedef struct
{
char string[10];
void get(void)
{
hiddenStringInput(string, 10);
return;
}
void set(const char* newPassword)
{
strcpy(string, newPassword);
return;
}
void show(void)
{
printf("%s", string);
return;
}
} password;
现在,我可以只调用userPassword.get(),userPassword.show()和userPassword.set(“ something”),然后发生的事情正是标签上所说的。有什么原因我不应该这样做吗?看起来很方便。
编辑:因此,这仅在C ++中是可能的。我没有意识到我正在使用C ++编译器,并且通过尝试做一些随机的事情,我想到了这个解决方案。所以这不是我真正想要的。