C语言中如何编写回调函数的示例代码?

2026-05-20 03:261阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计688个文字,预计阅读时间需要3分钟。

C语言中如何编写回调函数的示例代码?

前言:C++中使用class语法实现回调(当然,传统的C函数指针回调也是支持的)+ 例如,有人提供一个类库+ AfCopyFile,能够提供文件拷贝的功能,并且能通知用户当前的进度。+ int DoC()

前言

C++中使用class语法实现回调(当然,,旧式的C函数指针回调也是支持的)

比如,有人提供一个类库 AfCopyFile,能够提供文件拷贝的功能,而且能通知用户当前的进度。。。

int DoCopy(const char* source, const char* dst, AfCopyFileListener* listener);

用户只需要自己实现一个AfCopyFileListener对象,传给这个函数就行。。。

class MainJob : public AfCopyFileListener{ int OnCopyProgress(long long total, long long transfered){ } }

把Listener对象传过去

AfCopyFile af; af.DoCopy(source, dst, this);

回调机制的缺点:

无论是C语言的回调函数,还是C++里的Listener,都有一个共同的缺点:

它使代码逻辑变得难以阅读。。

我们应尽量避免使用回调机制,最好采用单向的函数调用。

示例代码:

AfCopyFile.h

#ifndef _AF_COPY_FILE_H #define _AF_COPY_FILE_H class AfCopyFile { public: // 作为内部类 class Listener { public: virtual int OnCopyProgress(long long total, long long transfered) = 0; }; public: int DoCopy(const char* source, const char* dst, Listener* listener); }; #endif

AfCopyFile.cpp

#include <stdio.h> #include <Windows.h> #include "AfCopyFile.h" // 将LARGE_INTTEGER类型转成unsigned long long inline unsigned long long translate(LARGE_INTEGER num) { unsigned long long result = num.HighPart; result <<= 32; result += num.LowPart; return result; } // 回调函数 // 注:要求将此函数用关键字CALLBACK修饰(这是Windows API的要求) static DWORD CALLBACK CopyProgress( LARGE_INTEGER TotalFileSize, LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID lpData) // <- 这个就是上下文件对象 { // 计算百分比 unsigned long long total = translate(TotalFileSize); unsigned long long copied = translate(TotalBytesTransferred); // 打印进度 AfCopyFile::Listener* listener = (AfCopyFile::Listener*) lpData; listener->OnCopyProgress(total, copied); return PROGRESS_CONTINUE; } int AfCopyFile::DoCopy(const char* source, const char* dst, Listener* listener) { BOOL ret = CopyFileEx(source, dst, &CopyProgress, // 待回调的函数 listener, // 上下文对象 NULL, 0); return ret ? 0 : -1; }

main.cpp

#include <stdio.h> #include <string.h> #include "AfCopyFile.h" class MainJob : public AfCopyFile::Listener { public: int DoJob() { strcpy(user, "shaofa"); strcpy(source, "c:\\test\\2.rmvb" ); strcpy(dst, "c:\\test\\2_copy.rmvb"); AfCopyFile af; af.DoCopy(source, dst, this); // 将this传过去 return 0; } int OnCopyProgress(long long total, long long transfered) { // 打印进度 int percent = (int) ( (transfered * 100 / total) ); printf("[用户: %s], %s -> %s : 进度 %d %%\n", user, source, dst, percent); return 0; } private: char source[256]; char dst[256]; char user[64]; }; int main() { MainJob job; job.DoJob(); return 0; }

总结

C语言中如何编写回调函数的示例代码?

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对自由互联的支持。

本文共计688个文字,预计阅读时间需要3分钟。

C语言中如何编写回调函数的示例代码?

前言:C++中使用class语法实现回调(当然,传统的C函数指针回调也是支持的)+ 例如,有人提供一个类库+ AfCopyFile,能够提供文件拷贝的功能,并且能通知用户当前的进度。+ int DoC()

前言

C++中使用class语法实现回调(当然,,旧式的C函数指针回调也是支持的)

比如,有人提供一个类库 AfCopyFile,能够提供文件拷贝的功能,而且能通知用户当前的进度。。。

int DoCopy(const char* source, const char* dst, AfCopyFileListener* listener);

用户只需要自己实现一个AfCopyFileListener对象,传给这个函数就行。。。

class MainJob : public AfCopyFileListener{ int OnCopyProgress(long long total, long long transfered){ } }

把Listener对象传过去

AfCopyFile af; af.DoCopy(source, dst, this);

回调机制的缺点:

无论是C语言的回调函数,还是C++里的Listener,都有一个共同的缺点:

它使代码逻辑变得难以阅读。。

我们应尽量避免使用回调机制,最好采用单向的函数调用。

示例代码:

AfCopyFile.h

#ifndef _AF_COPY_FILE_H #define _AF_COPY_FILE_H class AfCopyFile { public: // 作为内部类 class Listener { public: virtual int OnCopyProgress(long long total, long long transfered) = 0; }; public: int DoCopy(const char* source, const char* dst, Listener* listener); }; #endif

AfCopyFile.cpp

#include <stdio.h> #include <Windows.h> #include "AfCopyFile.h" // 将LARGE_INTTEGER类型转成unsigned long long inline unsigned long long translate(LARGE_INTEGER num) { unsigned long long result = num.HighPart; result <<= 32; result += num.LowPart; return result; } // 回调函数 // 注:要求将此函数用关键字CALLBACK修饰(这是Windows API的要求) static DWORD CALLBACK CopyProgress( LARGE_INTEGER TotalFileSize, LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID lpData) // <- 这个就是上下文件对象 { // 计算百分比 unsigned long long total = translate(TotalFileSize); unsigned long long copied = translate(TotalBytesTransferred); // 打印进度 AfCopyFile::Listener* listener = (AfCopyFile::Listener*) lpData; listener->OnCopyProgress(total, copied); return PROGRESS_CONTINUE; } int AfCopyFile::DoCopy(const char* source, const char* dst, Listener* listener) { BOOL ret = CopyFileEx(source, dst, &CopyProgress, // 待回调的函数 listener, // 上下文对象 NULL, 0); return ret ? 0 : -1; }

main.cpp

#include <stdio.h> #include <string.h> #include "AfCopyFile.h" class MainJob : public AfCopyFile::Listener { public: int DoJob() { strcpy(user, "shaofa"); strcpy(source, "c:\\test\\2.rmvb" ); strcpy(dst, "c:\\test\\2_copy.rmvb"); AfCopyFile af; af.DoCopy(source, dst, this); // 将this传过去 return 0; } int OnCopyProgress(long long total, long long transfered) { // 打印进度 int percent = (int) ( (transfered * 100 / total) ); printf("[用户: %s], %s -> %s : 进度 %d %%\n", user, source, dst, percent); return 0; } private: char source[256]; char dst[256]; char user[64]; }; int main() { MainJob job; job.DoJob(); return 0; }

总结

C语言中如何编写回调函数的示例代码?

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对自由互联的支持。