不知道如何导出Objective-C类。体系结构i386的未定义符号

问题描述 投票:3回答:3

我正在尝试在OSX上的GTK +上做一些工作,但遇到了一些麻烦,因为老实说,我对Objective-C并不那么熟悉。我有足够的编程经验,可以快速掌握基本语法,并且可以查找文档中需要的内容。但是我遇到的问题与链接库和将类暴露给要链接的程序有关。

GTK +是一个C库,但是OSX后端包括几个Objective-C类。它们不公开为公共API,仅在内部使用;但是对于我正在做的事情,我想尝试公开公开这些类。

供参考,这是类之一:

https://github.com/GNOME/gtk/blob/gtk-2-24/gdk/quartz/GdkQuartzWindow.hhttps://github.com/GNOME/gtk/blob/gtk-2-24/gdk/quartz/GdkQuartzWindow.c

我已经更改了构建系统,以便安装头文件。我有另一个源文件(在gtk +构建系统之外),其功能类似于:

GdkQuartzWindow *win = [[GdkQuartzWindow alloc] /* other messages... */ ];

当我尝试编译时,出现链接器错误:

Undefined symbols for architecture i386:
  ".objc_class_name_GdkQuartzWindow", referenced from:
  pointer-to-literal-objc-class-name in main-a8d029.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我对Objective-C编译器/链接器的工作方式不太熟悉,并且在理解如何(或如果可以)解决此问题时遇到麻烦。

[当我运行nm libgdk-quartz-2.0.dylib | grep GdkQuartzWindow时,我在该课程上看到很多消息:

00057120 t -[GdkQuartzWindow beginManualMove]
000575c0 t -[GdkQuartzWindow beginManualResize]
00056c50 t -[GdkQuartzWindow canBecomeKeyWindow]
... (many more) ...
000b2030 s .objc_class_name_GdkQuartzWindow

在该列表的底部,您看到链接器在抱怨的东西不存在。但是,如果我使用nm -g而不是nm,则不会显示任何内容,因此某些内容无法正确导出。

对于普通的C符号,构建过程将构建一个包含]的别名文件>

Apple's docs给我的印象是,当我的目标是i386(当前是它)时,这应该不是问题。他们说:

在32位OS X项目中,这些可见性控件仅适用于代码的C或C ++子集。它们不适用于Objective-C类和方法。 Objective-C类和消息名称是由Objective-C运行时而不是链接程序绑定的,因此可见性的概念不适用于它们。没有机制可以从动态库的客户端隐藏动态库中定义的Objective-C类或方法。

但是,我收到一条错误消息,说我有未定义的符号,因此我的错误似乎与此矛盾。如果我更改此行以便改为分配NSWindow,则一切正常。因此它可以正确导入AppKit内容。似乎在尝试公开类及其方法时做错了。

有人有机会向我指出正确的方向吗?

我正在尝试在OSX上的GTK +上做一些工作,但遇到了一些麻烦,因为老实说,我对Objective-C并不那么熟悉。我有足够的编程经验,因此很快就起床了...

objective-c linker clang
3个回答
1
投票

作为一种临时的解决方法,您可以通过将类名作为参数传递给NSClassFromString的调用来替换对代码中类符号的引用。例如:

GdkQuartzWindow *win = [[NSClassFromString(@"GdkQuartzWindow") alloc] /* other messages... */ ];

1
投票

我建议您在链接到GTK +时确保使用-ObjC标志。您可以将其添加到目标“构建设置”中的“其他链接器标志”下。如果这不起作用,则可以尝试添加-all_load链接器标志。


0
投票

我在混合C / C ++代码和ObjectiveC包装器的库中遇到类似的问题。在这种情况下,我正在使用-fvisibility=hidden gcc / clang标志编译整个库。这具有隐藏所有ObjectiveC类符号的直接​​效果。一种不太知名/不常用的技术是用可见性属性来装饰类。这广泛用于C / C ++,但也适用于ObjectiveC声明的类型。让我们首先创建一个OBJC_MYLIBRARY_API宏,该宏将使libdefs.h文件中的编译单元具有可见性:

© www.soinside.com 2019 - 2024. All rights reserved.