简体   繁体   English

Xcode 8更新后,通过桥接头的.c文件不起作用

[英].c File via Bridging Header Not Working After Xcode 8 Update

The app I've been working on uses an external library, pdlib, which has it's own externals (.c files) which I've been importing via the bridging header #import "Uzi.c" and calling in my main Swift file via Uzi.c's setup function Uzi_setup() in my ViewController class. 我一直在使用的应用程序使用一个外部库pdlib,它具有自己的外部文件(.c文件),我一直通过桥接头文件#import "Uzi.c"进行导入,并通过我的ViewController类中的Uzi.c的设置函数Uzi_setup() I've had no problem with this until after updating to new public Xcode 8 a few days ago (I had no problem with Xcode 8 Beta 1 over the Summer). 直到几天前更新到新的公共Xcode 8之前,我对此没有任何问题(整个夏天我对Xcode 8 Beta 1都没有问题)。

Here are the 7 errors I get, listed under a single "Mach-O Linker Error" umbrella: 这是我得到的7个错误,在单个“ Mach-O Linker错误”保护伞下列出:

Undefined symbols for architecture x86_64:
"_Uzi_bang", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_class", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_float", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_new", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_pause", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_resume", referenced from:
  _Uzi_setup in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Those undefined symbols are 6 functions and a class declare from Uzi.c. 这些未定义的符号是6个函数,并从Uzi.c声明一个类。 Here's a link to the whole c file: https://github.com/electrickery/pd-miXedSon/blob/master/hammer/Uzi.c 这是整个c文件的链接: https : //github.com/electrickery/pd-miXedSon/blob/master/hammer/Uzi.c

I've tried every solution I've found online for dealing with similar problems, with no solution yet... I tried changing the "Architecture" and "Valid Architecture" settings to only armv7 and armv7s (no arm64) and changed "Build Active Architecture Only" to "No". 我已经尝试过在网上找到的用于解决类似问题的所有解决方案,但还没有解决方案...我尝试将“ Architecture”和“ Valid Architecture”设置更改为仅armv7和armv7s(无arm64),并更改了“构建”仅活动架构”到“否”。 These step seem to help others in similar situations, but they didn't work for me (and taking away arm64 causes additional errors to appear). 这些步骤似乎可以在类似的情况下帮助其他人,但是它们对我没有用(拿走arm64会导致出现其他错误)。

XCode 8 is pretty recent (the public version was released Sept. 13), so there are virtually no other questions about this upgrade causing a similar problem. XCode 8是最近才发布的(公共版本于9月13日发布),因此实际上没有关于此升级引起类似问题的其他问题。

Any help would be greatly appreciated! 任何帮助将不胜感激!

Solved by @danomatika on GitHub: https://github.com/libpd/libpd/issues/149 由@danomatika在GitHub上解决: https : //github.com/libpd/libpd/issues/149

"You generally shouldn't include/import an implementation file aka .c, .cpp, .m, etc. This is what is causing the duplicate symbol issue. “通常,您不应该包括/导入.c,.cpp,.m等实现文件。这就是导致重复符号问题的原因。

This is what the "forward function declaration" in the header file is for: to tell the compiler that a function exists and what data it takes/returns. 这是头文件中“转发函数声明”的作用:告诉编译器函数存在以及它获取/返回的数据。 The compiler then assumes the actual implementation of the function exists in an implementation file. 然后,编译器假定功能的实际实现存在于实现文件中。 If it can't be found, then you get an "undefined symbol error." 如果找不到,则会出现“未定义符号错误”。 If you somehow end up declaring the function twice, aka include both a header with the forward declaration and the implemetaton of the function itself in the .c file, then you get a "duplicate symbol error." 如果以某种方式最终两次声明了该函数,又在.c文件中同时包含了带有正向声明的标头和函数本身的实现,那么您将收到“重复符号错误”。

This is all lower-level stuff that is only really an issue since Pd externals are designed around being dynamic libraries, so are not built or provided with headers which include the function declarations. 由于Pd外部对象是围绕动态库而设计的,因此这些较低层的东西只是一个真正的问题,因此它们并未构建或未提供包含函数声明的标头。 This is why you have to do a little extra work and do it yourself. 这就是为什么您需要做一些额外的工作然后自己做的原因。

Their are two easy fixes for this, both of which involve declaring the required function you want to call from the .c file in a header file. 它们是两个简单的修复程序,都涉及在头文件中声明要从.c文件调用的必需函数。

  1. Simply declare the function in the bridging header: 只需在桥接头中声明函数:

    void uzi_setup();

  2. Create a header, say Externals.h, and declare all of the externals stuff there: 创建一个标题,例如Externals.h,并在其中声明所有外部元素:

    // forward declare setup functions only found in .c implementations void uzi_setup();

    // convenience wrapper function void externals_setup() { uzi_setup(); }

    Then import the file in your bridging header: 然后将文件导入桥接头中:

    #import "Externals.h"

    And in swift, you can now do: 而且,您现在可以执行以下操作:

    externals_setup()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM