与Swift的C类进行交互

前端之家收集整理的这篇文章主要介绍了与Swift的C类进行交互前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个重要的C类图书馆。我试图通过Swift中的某种类型的桥梁来使用它们,而不是将它们重写为Swift代码。主要的动机是C代码表示在多个平台上使用的核心库。实际上,我只是创建一个基于Swift的UI,以允许核心功能在OS X下工作。

还有其他问题,“如何调用Swift的C函数。”这不是我的问题。要桥接到C函数,以下工作正常:

通过“C”定义桥接头

  1. #ifndef ImageReader_hpp
  2. #define ImageReader_hpp
  3.  
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7.  
  8. const char *hexdump(char *filename);
  9. const char *imageType(char *filename);
  10.  
  11. #ifdef __cplusplus
  12. }
  13. #endif
  14.  
  15. #endif /* ImageReader_hpp */

Swift代码现在可以直接调用函数

  1. let type = String.fromCString(imageType(filename))
  2. let dump = String.fromCString(hexdump(filename))

我的问题更具体。如何在Swift内实例化和操作C类?我似乎找不到任何发表的内容

我已经找出了一个完美可控的答案。你想要这么干净,完全取决于你愿意做多少工作。

首先,拿你的C类并创建C“wrapper”函数来与它进行接口。例如,如果我们有这个C类:

  1. class MBR {
  2. std::string filename;
  3.  
  4. public:
  5. MBR (std::string filename);
  6. const char *hexdump();
  7. const char *imageType();
  8. const char *bootCode();
  9. const char *partitions();
  10. private:
  11. bool readFile(unsigned char *buffer,const unsigned int length);
  12. };

然后我们实现这些C函数

  1. #include "MBR.hpp"
  2.  
  3. using namespace std;
  4. const void * initialize(char *filename)
  5. {
  6. MBR *mbr = new MBR(filename);
  7.  
  8. return (void *)mbr;
  9. }
  10.  
  11. const char *hexdump(const void *object)
  12. {
  13. MBR *mbr;
  14. static char retval[2048];
  15.  
  16. mbr = (MBR *)object;
  17. strcpy(retval,mbr -> hexdump());
  18. return retval;
  19. }
  20.  
  21. const char *imageType(const void *object)
  22. {
  23. MBR *mbr;
  24. static char retval[256];
  25.  
  26. mbr = (MBR *)object;
  27. strcpy(retval,mbr -> imageType());
  28. return retval;
  29. }

桥头包含:

  1. #ifndef ImageReader_hpp
  2. #define ImageReader_hpp
  3.  
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7.  
  8. const void *initialize(char *filename);
  9. const char *hexdump(const void *object);
  10. const char *imageType(const void *object);
  11.  
  12. #ifdef __cplusplus
  13. }
  14. #endif
  15.  
  16. #endif /* ImageReader_hpp */

从Swift,我们现在可以实例化对象并与之进行交互,如下所示:

  1. let cppObject = UnsafeMutablePointer<Void>(initialize(filename))
  2. let type = String.fromCString(imageType(cppObject))
  3. let dump = String.fromCString(hexdump(cppObject))
  4. self.imageTypeLabel.stringValue = type!
  5. self.dumpDisplay.stringValue = dump!

因此,您可以看到,解决方案(实际上相当简单)是创建将实例化对象并返回指向该对象的指针的包装器。然后可以将其传回到包装器函数中,该函数可以轻松地将其视为符合该类的对象并调用成员函数

使其更清洁

虽然这是一个奇妙的开始,并证明使用现有的C类与简单的桥梁是完全可行的,它可以更清洁。

清理这个只是意味着我们删除了UnsafeMutablePointer< void>从我们Swift代码的中间,将其封装成Swift类。本质上,我们使用相同的C/C++包装函数,但是将其与Swift类接口。 Swift类维护对象引用,并且基本上只是通过桥将所有方法属性引用调用传递给C对象!

完成此操作后,所有桥接代码都完全封装在Swift类中。尽管我们仍在使用C桥,但我们正在透明地使用C对象,而无需在Objective-C或Objective-C中重新编码它们。

猜你在找的Swift相关文章