-2

在 api.h

typedef void* hidden_my_type;
void do_something(my_type x);

在 core.c 中

struct _my_type
{
    int a;
}

void do_something(hidden_my_type void_x)
{
   struct *_my_type x = void_x;  /*Don't understand is that correct way to do, as I'm getting segmentation fault error */
   printf("Value: %d\n", x->a);
}

我认为的其他方式,

struct *_my_type x = (struct _my_type *)malloc(sizeof(struct _my_type));
void_x = x
printf(Value: %d\n", x->a);

但我仍然收到段错误错误。


好的,这里是 void*.... 的问题。

例如在 core.c

void init_my_type(hidden_my_type a)
{
   my_type *the_a = malloc(...);
   a = the_a   // <<<<<<<<<<<<<<<<<<<<<<<<<<<< is this correct?! a is void* and the_a // is original type
   pthread_cond_init(&the_a->...);
    .. (in short any other methods for init ..)
}
void my_type_destroy(my_hidden_type x)
{
    my_type *the_x = x;
    pthread_detroy(&the_x-> ...);
}

在 main.c

test()
{
   my_hidden_type x;
   init_my_type(x);
   .... 
   my_type_detroy(x);
}

这它自己应该失败。就像在 main.c 测试函数中一样, x 是 void* ... init 将分配,但在销毁时我再次传递 void* .. 这可以是任何东西!

编辑(为我解决)

在 api.h

typedef void* hidden_my_type;
void do_something(my_type x);

在 core.c 中

 struct _my_type
    {
        int a;
    }


 void init_hidden_type(hidden_my_type void_p_my_type)
    {
        struct _my_type *real_my_type = (struct _my_type *)malloc(sizeof(struct _my_type));
        //--- Do init for your type ---
        void_p_my_type = real_my_type;
    }


 void do_something(hidden_my_type void_x)
    {
       struct *_my_type x = void_x; 
       printf("Value: %d\n", x->a);
    }
4

2 回答 2

1

版本 0 — 问题代码批判

发布的代码无法编译。

api.h

typedef void* hidden_my_type;
void do_something(my_type x);

这定义hidden_my_type但不是my_type传递给do_something(). 大概,你打算:

typedef void *my_type;
void do_something(my_type x);

核心.c

struct _my_type
{
    int a;
}

如下所述,结构定义后缺少分号。

void do_something(hidden_my_type void_x)
{
   struct *_my_type x = void_x;
   printf("Value: %d\n", x->a);
}

你又遇到了hidden_my_typevsmy_type问题。你有*指针不能去的地方;它必须在struct _my_type. 你可能打算这样:

void do_something(my_type void_x)
{
   struct _my_type *x = void_x;
   printf("Value: %d\n", x->a);
}

这现在在语法上是正确的(我认为;我实际上并没有通过编译器运行它)。你还没有展示它是如何使用的;实际上,由于用户代码无法生成指向有效结构的指针,因此无法安全地使用此代码。

您的测试代码(未显示 - 为什么不显示您的测试代码)可能看起来像这样:

#include "api.h"

int main(void)
{
    my_type x = 0;
    do_something(x);
    return 0;
}

或者,它可能没有= 0适当的初始化程序。无论哪种方式,您的代码都无法正常运行,并且核心转储几乎是不可避免的。当您向用户隐藏结构时,您必须为他们提供一种机制来获取有效的(指向)结构的(指针),而您还没有这样做。

版本 1

这是一种更好的方法,因为它更接近类型安全:

api.h 版本 1

typedef struct _my_type *my_type;
void do_something(my_type x);

core.c 版本 1

#include "api.h"
struct _my_type
{
    int a;
};

注意添加的分号和api.h文件的包含。

void do_something(my_type x)
{
    // Now you don't have to do casting here!
    //struct *_my_type x = void_x;  /*Don't understand is that correct way to do, as I'm getting segmentation fault error */
    printf("Value: %d\n", x->a);
}

版本 2

实际上,我们可以讨论隐藏指针的智慧;我宁愿不这样做:

api.h 版本 2

#ifndef API_H_INCLUDED
#define API_H_INCLUDED

typedef struct my_type my_type;
extern void     do_something(my_type *x);
extern my_type *my_type_initializer(void);
extern void     my_type_release(my_type *x);

#endif /* API_H_INCLUDED */

core.c 版本 2

#include "api.h"
#include <stdio.h>
#include <stdlib.h>

struct my_type
{
    int a;
};

void do_something(my_type *x)
{
    printf("Value: %d\n", x->a);
}

my_type *my_type_initializer(void)
{
    my_type *x = malloc(sizeof(*x));
    x->a = 57;  // More plausibly, this would be 0
    return x;
}

void my_type_release(my_type *x)
{
    free(x);
}

主程序

#include "api.h"

int main(void)
{
    my_type *x = my_type_initializer();
    do_something(x);
    my_type_release(x);
    return 0;
}

这很好,很干净。当然,用户不能分配一个struct my_type(只有一个指向它的指针),所以你需要一个函数来为他们分配结构。想想标准C库,FILE类型,fopen()分配和fclose()释放fprintf()等等来操作类型。my_type_initializer()是 的 类似物,fopen()类似物my_type_release(),fclose()do_something()类似物fprintf()

于 2012-04-17T00:35:19.060 回答
0

乔纳森,你打败了我,但这也可能有帮助。在这里,api.c包含(私有)实现,并api.h提供其他代码使用的接口,例如main.c.

// main.c: uses only the public interface to the private code
#include "api.h"

int main(int argc, char *argv[]) {
  void *foo;

  foo = create_foo("five", 5);
  print_foo(foo);
  delete_foo(foo);
}
// EOF main.c


// api.h: the public interface
#ifndef _api_h_
#define _api_h_
void *create_foo(char *name, int number);
void print_foo(void *foo);
void delete_foo(void *foo);
#endif // _api_h_


// api.c: the private implementation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// The real structure is private to the implementation.
typedef struct {
        char name[20];
        int number;
} real_struct;

// Create a new structure, initialize, return as ptr-to-void.
void *create_foo(char *name, int number) {
  real_struct *s = malloc(sizeof(real_struct));
  strcpy(s->name, name);
  s->number = number;
  return (void *) s;
}

// Print the data.
void print_foo(void *foo) {
  real_struct *s = (real_struct *) foo;
  printf("name: %s, number: %d\n", s->name, s->number);
}

// Release the memory.
void delete_foo(void *foo) {
  free(foo);
}
// EOF api.c

此代码应编译并运行:

$ gcc -o foo main.c api.c
$ ./foo

name: five, number: 5
于 2012-04-17T01:01:10.337 回答