我有一段C代碼的工作示例,我正在使用它來教導自己如何在非平凡應用程序中有效使用指針。 (我有一個夢想貢獻缺少功能一個C庫,我靠。)在通用訪問器函數中使用void指針ANSI C
我的示例代碼廁所這樣的:
#include <stdio.h>
#include <stdlib.h>
struct config_struct {
int port;
char *hostname;
};
typedef struct config_struct config;
void setup(config*);
void change(config*);
void set_hostname(config*, char*);
void get_hostname_into(config*, char**);
void teardown(config*);
void inspect(config*);
int main() {
char* hostname;
config* c;
c = calloc(1, sizeof(config));
setup(c);
inspect(c);
change(c);
inspect(c);
set_hostname(c, "test.com");
inspect(c);
get_hostname_into(c, &hostname);
inspect(c);
printf("retrieved hostname is %s (%p)\n", hostname, &hostname);
teardown(c);
printf("retrieved hostname is %s (%p) (after teardown)\n", hostname, &hostname);
return EXIT_SUCCESS;
}
void setup(config* c) {
c->port = 9933;
c->hostname = "localhost";
}
void change(config* c) {
c->port = 12345;
c->hostname = "example.com";
}
void set_hostname(config* c, char* new_hostname) {
c->hostname = new_hostname;
}
void get_hostname_into(config* c, char** where) {
*where = c->hostname;
}
void teardown(config* c) {
free(c);
}
void inspect(config* c) {
printf("c is at %p\n", c);
printf("c is %ld bytes\n", sizeof(*c));
printf("c:port is %d (%p)\n", c->port, &(c->port));
printf("c:hostname is %s (%p)\n", c->hostname, &(c->port));
}
它需要通過庫的性質(中函數是get_session_property(session*, enum Property, void*)
- 因此我正在尋找一種解除引用無效指針的方法;我能夠成功實現這個爲int
,但一直在踢我的腳後跟,試圖找出如何做到這一點char*
(關於void*
到int
有一定道理,但我無法想象如何去做void* to char*
。
我的成功實施(有測試)是在我的項目的Github分支上,here。
我來最接近的是:
enum Property { Port, Hostname };
void get_property(config*, enum Property, void*);
void get_property(config* c, enum Property p, void* target) {
switch(p) {
case Port:
{
int *port;
port = (int *) target;
*port = c->port;
}
break;
case Hostname:
{
char *hostname;
hostname = (char *) target;
*hostname = c->hostname;
}
break;
}
}
哪個仁慈不段錯誤,但也留下char *get_hostname_into_here
null
,提高預警(我想不出:)
untitled: In function ‘get_property’:
untitled:33: warning: assignment makes integer from pointer without a cast
我在這裏設計的例子的完整源代碼;請在回答解釋時,或者推薦您使用void指針和/或C風格的任何閱讀時,似乎每個人都有不同的想法,並且我在現實世界中認識的幾個人只是說「圖書館正在這樣做錯誤的,不要使用void指針) - 雖然它會很好,如果庫會公開結構;對於封裝和其他很好的理由,我認爲在這種情況下void指針,通用函數的方法是完全合理的
所以,我在我的get_property()
功能的char*
是NULL
調用get_property(c, Hostname, &get_hostname_into_here);
hostname
分支做錯了
full source code for example (with output)。
我不是100%清楚這裏的目標是什麼,但是'void *'的替代可能是基於'union'的。 –
在'Hostname'的情況下,'target'指向什麼?一個char *'?一個'char'緩衝區?這裏有什麼意圖的語義? (不知道這個,不可能回答你的問題。) –
有兩個問題,就我所知,我沒有辦法事先知道緩衝區應該多大,所以我認爲'target'必須是' char *' - 我無法預先分配我自己的空間。我期望這將意味着配置被釋放後,我的'目標'將是段默認的領土,這是可以的。 –