如何使用 C++ 方式来编写驱动

这个问题可能会很无聊,而且觉得连这个题目都不好拟,但我还是以我的方式记下来了,觉得有用的朋友就尽管拿去用,不过我觉得可能性很小

问题的由来:
        c源文件是以"c"为后缀的 ,而纯c语言都是在函数的开始就将所有用的变量全部定义好,然后在函数中使用,如果不按照这个规定,那么等待你的就是在编译的时候将你处以极刑,这个让我觉得非常郁闷,我就是想在使用的时候再定义一个变量,这样可以让我的程序更加让自己读懂,因此就产生了这个话题 "如何使用 C++ 方式来编写驱动"

问题的解决:
        既然"c"后缀的不行,那么我改为"cpp"吧,这样就不是C++了吗(...呵呵..大家为我的聪明鼓掌吧),编译一下试试,你爷爷的,怎么这么多的unresolved external symbol哦,每个函数都跟我抗议了,(做出这么大的动作,有必要吗?)
        当时想了很久,后来终于知道是C++重载机制捣蛋了,那好,我加extern "C"

#ifdef __cplusplus 
extern   " C "  

#endif 

#include 
"ntddk.h"

#ifdef __cplusplus 
}
 
#endif

我把头文件前面加上extern "C",编译,果然成功了,原来就这么简单的说,不错不错,我现在终于可以在任何地方定义变量了...舒坦啊!!

紧急问题的出现:
        编译通过了.上战场试试,晕啊,蓝屏,我以前好好的代码,这么拿过来就蓝屏了呢?到softice里面单步调,发现很奇怪的现象,在我调用PsLookupProcessByProcessId的时候就导致蓝屏了,这个就很奇怪了,这个函数是ntoskrnl导出的,声明不是就可以用了吗?这里会存在什么问题呢?想了很久想不通

NTSTATUS PsLookupProcessByProcessId(
     IN ULONG ulProcId, 
     OUT PEPROCESS 
*  pEProcess
     );

        拿出内核调试器看看PsLookupProcessByProcessId的地址,我靠,终于被我逮到,我程序里面的PsLookupProcessByProcessId的地址和内核调试器的地址完全不同,程序里面的PsLookupProcessByProcessId地址竟然在该程序模块里面
       原来又是C++的重载机制搞的鬼啊,我声明的PsLookupProcessByProcessId由于C++和C编译的区别,导致无法在ntoskrnl中找到原型,因此它自立门户了,加个extern "C"试试,果然成功

说来说去还是extern "C"的问题,哦..了解了

谢谢阁下花时间看了这莫名其妙的文章..真的莫名堂啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 我可以为您提供一个示例,您可以使用它来编写驱动代码:#include <stdio.h>int main() { int device_id; char *buffer; unsigned int size; //读取设备 printf("请输入设备ID:"); scanf("%d", &device_id); //读取缓冲区 printf("请输入缓冲区:"); scanf("%s", buffer); //读取缓冲区尺寸 printf("请输入缓冲区尺寸:"); scanf("%u", &size); //打开设备 int fd = open("/dev/mydevice", O_RDWR); //入缓冲区 write(fd, buffer, size); //读取缓冲区 read(fd, buffer, size); //关闭设备 close(fd); return 0; } ### 回答2: 驱动程序是操作系统中非常重要的组成部分,它负责管理硬件设备与操作系统之间的通信。下面是一个使用C语言编写驱动程序代码的示例: 首先,我们需要包含一些头文件,以便在代码中使用相关的函数和变量。例如: ``` #include <linux/module.h> // 包含模块编程相关的头文件 #include <linux/kernel.h> // 包含内核相关的头文件 #include <linux/fs.h> // 包含文件系统相关的头文件 #include <linux/uaccess.h> // 包含内核用户空间通信相关的头文件 ``` 接下来,我们定义一个变量来保存设备的主设备号(major number)。主设备号用于标识设备的类型。 ``` dev_t device_number; ``` 然后,在驱动程序的初始化函数中,我们可以使用`alloc_chrdev_region()`函数来动态分配主设备号。该函数的原型如下: ``` int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); ``` 接着,我们需要实现`read()`和`write()`函数来读取和入设备。 在`read()`函数中,我们可以使用`copy_to_user()`函数将内核空间的数据复制到用户空间中。例如: ``` ssize_t my_read(struct file *filp, char __user *buffer, size_t length, loff_t *offset){ // 从设备中读取数据 // 将数据复制到用户空间的buffer中 copy_to_user(buffer, data, length); // 返回实际读取的字节数 return length; } ``` 在`write()`函数中,我们可以使用`copy_from_user()`函数将用户空间的数据复制到内核空间中。例如: ``` ssize_t my_write(struct file *filp, const char __user *buffer, size_t length, loff_t *offset){ // 从用户空间的buffer中读取数据 // 将数据入设备 copy_from_user(data, buffer, length); // 返回实际入的字节数 return length; } ``` 最后,在驱动程序的初始化函数中,我们需要进行各种注册操作,以确保驱动程序能够正常工作。例如: ``` // 注册字符设备驱动程序 cdev_init(&my_cdev, &my_file_operations); my_cdev.owner = THIS_MODULE; my_cdev.ops = &my_file_operations; // 添加字符设备到系统 int result = cdev_add(&my_cdev, device_number, 1); ``` 以上是一个简单的驱动程序代码示例。实际的驱动程序可能涉及更多的功能和操作,具体的实现方式还取决于设备的类型和应用场景。编写驱动程序需要深入了解底层硬件和操作系统的相关知识,以确保稳定和安全地与硬件设备进行通信。 ### 回答3: 使用C语言编写驱动程序,可以通过操作系统提供的系统调用接口来实现设备的读操作。以下是一个简单的示例代码: ```c #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; char buffer[1024]; // 打开设备文件 fd = open("/dev/device", O_RDWR); if (fd < 0) { printf("无法打开设备文件\n"); return -1; } // 读取设备数据 if (read(fd, buffer, sizeof(buffer)) < 0) { printf("读取设备数据失败\n"); close(fd); return -1; } // 处理设备数据 printf("设备数据:%s\n", buffer); // 入设备数据 char data[] = "Hello, device!"; if (write(fd, data, sizeof(data)) < 0) { printf("入设备数据失败\n"); close(fd); return -1; } // 关闭设备文件 close(fd); return 0; } ``` 上述代码首先使用`open`函数打开设备文件`/dev/device`,其中`/dev/device`是待读的设备文件的路径。通过指定`O_RDWR`标志,可以以读模式打开设备。 然后,使用`read`函数读取设备数据进入缓冲区`buffer`,并通过`sizeof(buffer)`确定读取数据的大小。 接下来,对读取到的设备数据进行处理,这里仅仅是简单地将其打印出来。 最后,使用`write`函数将数据`"Hello, device!"`入设备。 最后,使用`close`函数关闭设备文件。 需要注意的是,上述代码仅仅是一个示例,具体的驱动操作实现取决于设备的特性和驱动模型,可能需要使用不同的函数和参数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值