C 错误:取消引用指向不完整类型的指针->;将结构传递给模块

C 错误:取消引用指向不完整类型的指针->;将结构传递给模块,c,pointers,struct,module,C,Pointers,Struct,Module,结构: #include <gtk/gtk.h> #include "db_interface.h" struct AddNewEmployee { const gchar *fname; const gchar *lname; }; void new_emp_get_data(GtkWidget *widget, gpointer add_emp_window) { struct AddNewEmplo

结构:

    #include <gtk/gtk.h>
    #include "db_interface.h"

    struct AddNewEmployee {
    const gchar *fname;
    const gchar *lname;
    };

    void new_emp_get_data(GtkWidget *widget, gpointer add_emp_window)
    {
      struct AddNewEmployee n_e_s; //new employee struct

      <gtk portion removed to clean code> 

      n_e_s.fname=gtk_entry_get_text(GTK_ENTRY(first));
      n_e_s.lname=gtk_entry_get_text(GTK_ENTRY(last));

      db_add_new_emp(&n_e_s); //pass the struct to db_interface to add new employee
    }
第二个模块(db_interface.c)

#包括
#包括“db_interface.h”
void db_add_new_emp(结构AddNewEmployee*n_e_s)
{
printf(“来自数据库接口的问候语,%s\n”,n\u e\u s->fname);
}

当我尝试使用GCC编译代码时,我得到消息“error:dereferencepointtocomplete type”。我尝试了几个不同的答案,当其他人发布他们关于这个错误的问题时,我发现了它们,但还没有找到一个有效的答案。我将函数中的代码从db_interface.c模块复制到原始模块(包含struct的模块),它工作得很好,因此我知道我的问题在于将结构发送到db_interface.c模块。

只需将struct
AddNewEmployee
移动到db_interface.h,它就可以正常编译。
两个.c文件都需要知道结构是如何实现的。

因为我们显然看不到这里的全部代码,所以无法确定全局
struct AddNewEmployee*n\u e\s将永远不会被使用。然而,我对第一段投了+的赞成票:解决方案确实是将结构移动到头文件。对,我认为我应该更好地改变这一点。但是,如果它是全局的,那么它缺少一个
extern
。这将导致其他编译器错误。编译器在引用它的每个C文件中都包含一个头文件(
.h
)。因此,将声明放在头文件中等同于将声明放在C文件的顶部。我看不需要任何
extern
关键字。当您计划从单独编译的文件(不同的
.o
)访问当前文件中定义的变量时,需要使用
extern
关键字。但是如果您在头文件中声明全局变量并将其包含在多个位置,例如在本例中,您将得到符号重新定义,因为该变量不是本地(静态)变量,不?不,你是对的,这和保安无关。如果头文件在C文件中包含多次,那么include-guard可以在编译时避免名称冲突(使用
gcc-E
在预处理后查看C代码)。符号未重新定义的事实来源于符号名称不再存在于任何对象中。因此,当将结构包含在n个对象中时,您将拥有n次结构,但每个对象都将使用自己的结构,没有任何冲突:结构的名称将不再以二进制形式存在,只有它们的偏移量。请注意,变量
struct AddNewEmployee*n\u e\s和在
void db_add_new_emp(struct AddNewEmployee*n_e_s)
中使用的参数名完全相同。这是有效的C代码,将编译。某些编译器会根据编译器标志向您发出警告,但这应该避免,因为这很可能会导致运行时错误。您应该更改其中一个名称。我同意@glampert的观点,即在不同范围内为两个变量使用相同的名称可能会导致误导情况(在
db\u add\u new\u emp
函数中,如何访问全局
n\u e\u s
变量?),而只需更改这些变量中的任何一个的名称,就可以很容易地避免这种情况。
    #ifndef DB_INTERFACE_H
    #define DB_INTERFACE_H

    struct AddNewEmployee *n_e_s;
    void db_add_new_emp(struct AddNewEmployee *n_e_s);

    #endif
    #include <stdio.h>
    #include "db_interface.h"

    void db_add_new_emp(struct AddNewEmployee *n_e_s)
    {
      printf("Greetings from db_interface, %s\n", n_e_s->fname);
    }