C 在多个源文件上创建内核模块时有多个定义

C 在多个源文件上创建内核模块时有多个定义,c,linker,makefile,kernel-module,C,Linker,Makefile,Kernel Module,我认为问题在于有一个头文件包含源文件所需的所有项,但如何解决这个问题?是否可以使用一个或我必须将它们与它们自己的包含功能分开 我不确定所有源文件中包含的.h文件有什么问题。我了解到问题是每个源文件都是用这个.h文件单独编译的,当将所有源文件链接在一起时,编译会发现有多个定义,即使我有一个include-guard 我该怎么办?这里有prototype.h,它包括我所有的函数原型,包括,外部变量和结构。我有一些源文件都需要这个.h文件的一部分 我的make文件如下 TARGET = betty

我认为问题在于有一个头文件包含源文件所需的所有项,但如何解决这个问题?是否可以使用一个或我必须将它们与它们自己的包含功能分开

我不确定所有源文件中包含的.h文件有什么问题。我了解到问题是每个源文件都是用这个.h文件单独编译的,当将所有源文件链接在一起时,编译会发现有多个定义,即使我有一个include-guard

我该怎么办?这里有prototype.h,它包括我所有的函数原型,包括,外部变量和结构。我有一些源文件都需要这个.h文件的一部分

我的make文件如下

TARGET = betty

obj-m := $(TARGET).o

betty-objs := main.o helpers.o syscall_overrides.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
    $(RM) .*.cmd *.o *.ko -r .tmp* 
其中一部分给出的错误消息是:

/home/admin/Dropbox/COMP3000/FinalModule/helpers.o:(.bss+0x4): multiple definition of `clean_sys_mkdir'
/home/admin/Dropbox/COMP3000/FinalModule/main.o:(.bss+0x0): first defined here
/home/admin/Dropbox/COMP3000/FinalModule/helpers.o:(.bss+0x8): multiple definition of `clean_sys_execve'
/home/admin/Dropbox/COMP3000/FinalModule/main.o:(.bss+0x4): first defined here
/home/admin/Dropbox/COMP3000/FinalModule/helpers.o:(.bss+0xc): multiple definition of `clean_getdents64_syscall'
代码:

main.c

#define MODULE_NAME "Betty"

#include "prototypes.h"

extern unsigned long **syscall_table;

static int __init init(void)
{
    ...
}

static void __exit shutdown(void)
{
   ...
}

module_init(init);
module_exit(shutdown);

MODULE_LICENSE("..");
MODULE_AUTHOR("..");
MODULE_DESCRIPTION("..");
原型.h

#ifndef PROTOTYPE_H
#define PROTOTYPE_H

#include <linux/module.h>    // mandatory kernel module 
#include <linux/kernel.h>    // KERN_INFO
#include <linux/init.h>      // __init and __exit
#include <asm/unistd.h>      // __NR syscall nums
#include <linux/printk.h>
#include <linux/tty.h>       // tty_struct
#include <linux/tty_driver.h>// write (already included by tty.h)
#include <linux/sched.h>     // current
#include <linux/random.h>    // get_random_bytes
#include <linux/syscalls.h>  // from sys_execve asmlinkage 
#include <linux/dirent.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/slab.h>      // kmalloc()
#include <linux/time.h>      // time
#include <linux/rtc.h>             // rtc_time_to_tm

/*
  Function prototypes for both original and custom syscalls that Betty uses
*/
asmlinkage long (*clean_sys_mkdir)(const char __user *pathname, umode_t mode);
asmlinkage long (*clean_sys_execve)(const char __user *filename,
                const char __user *const __user *argv,
                const char __user *const __user *envp);
asmlinkage long (*clean_getdents64_syscall) (unsigned int fd,
            struct linux_dirent64 __user * dirent,
            unsigned int count);

static void find_process_id_to_hide(char* process_nm);

extern unsigned long **syscall_table;


#endif

请显示您的代码。@kaylum我已经用一个部分对其进行了更新,以限制其大小。你认为这个错误可能是源于代码吗?好吧,我明白你为什么问我。包含的每个源文件都应该有一个包含保护,这是我在源文件中遗漏的。现在的问题是,我的其他源文件如何访问任务变量,如current或。。。NULL,它们似乎未在我的其他源文件中声明。似乎我的其他源文件需要prototype.h来编译如果一些源文件需要东西,直接在prototype.h中声明,那么它可以包含这个头文件。如果源文件只需要在system headerlike current中定义的东西,那么它可以直接包含对应的头:include。但包括整个原型。h也可以。顺便说一句,您的代码使用-include-prototype.h-,但您帖子中的其他文本将其称为prototype.h。文件的实际名称是什么?
#include "prototypes.h"

extern unsigned long **syscall_table; // extern variable 

... just functions in this one defined in prototype.h