不确定如何导出Objective-C类.体系结构i386的未定义符号 [英] Not sure how to export Objective-C classes. Undefined symbols for architecture i386

查看:101
本文介绍了不确定如何导出Objective-C类.体系结构i386的未定义符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

作为参考,下面是其中的一种:

https://github.com/GNOME/gtk/blob/gtk-2-24/gdk/quartz/GdkQuartzWindow.h https://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的文档给我当我的目标是i386(当前是它)时,这应该不是问题的印象.他们说:

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

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

有没有机会有人可以向我指出正确的方向?

解决方案

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

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

但是,这具有长期可维护性问题,因为它取决于保持不变的类的名称.我怀疑对于当前的编译器,Apple文档可能已过时或错误.也许要检查一下gdk/quartz/Makefile.in中用$(GDK_HIDDEN_VISIBILITY_CFLAGS)替换的值是否确实是平台上的空字符串,如果不是,则更改该字符串可能是满足您需求的更可行的长期解决方案.

I'm trying to do some work on GTK+ on OSX and I'm having a little trouble because, to be honest, I'm not all that familiar with Objective-C. I have enough programming experience that I quickly got up to speed on the basic syntax, and I can look up what I need in documentation. But the problems I'm having are related to linking the library and exposing the classes to the program I'm linking to.

GTK+ is a C library, but the OSX backend includes a couple Objective-C classes. They're not exposed as public API, they're only used internally; but for something I'm working on I'd like to try to expose these classes publicly.

For reference, here is one of the classes:

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

I've changed the build system so that it installs the header files. I have another source file (outside the gtk+ build system) that does something like:

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

When I try to compile I get a linker error:

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)

I'm not very familiar with how Objective-C compiler/linker works and having trouble understanding how I can (or if I can) solve this.

When I run nm libgdk-quartz-2.0.dylib | grep GdkQuartzWindow I see a lot of messages on this class:

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

At the bottom of that list, you see the thing that the linker is complaining doesn't exist. But if I use nm -g instead of nm then nothing is shown, so something is not being exported correctly.

For normal C symbols, the build process builds an alias file that includes

Apple's docs give me the impression that this shouldn't be a problem when my target is i386 (which it currently is). They say:

In a 32-bit OS X project, these visibility controls apply only to the C or C++ subset of your code. They do not apply to Objective-C classes and methods. Objective-C class and message names are bound by the Objective-C runtime, not by the linker, so the notion of visibility does not apply to them. There is no mechanism for hiding an Objective-C class or method defined in a dynamic library from the clients of that library.

But, I am receiving an error saying I have undefined symbols, so my error seems to contradict this. If I change this line so that it's allocating an NSWindow instead, everything works fine; so it's importing the AppKit stuff correctly. It just seems that I'm doing something wrong with trying to expose the classes and their methods.

Any chance someone can point me in the right direction?

解决方案

As a temporary workaround, you could replace references to the class symbol in your code with calls to NSClassFromString passing the class name as an argument. For example:

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

This has long-term maintainability issues, though, as it depends on the name of the class remaining unchanged. I suspect that the Apple doc may be out of date or wrong for current compilers. Perhaps check to see if the value being substituted in gdk/quartz/Makefile.in for $(GDK_HIDDEN_VISIBILITY_CFLAGS) indeed is the empty string on your platform, and if not, changing that may be a more viable long term solution for your needs.

这篇关于不确定如何导出Objective-C类.体系结构i386的未定义符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆