0

我在当前的 Xcode 4.6 项目中添加了一个 obj-c 类(.mm 和 2 个头文件)。一个头文件具有调用 obj-c 类的原型,另一个定义了 .mm 类。这是它的样子。

我的界面.h

#ifndef MYINTERFACE_H
#define MYINTERFACE_H

BOOL LaunchApp(CAtlString exePath);

#endif

我的LaunchClass.h

#import "myinterface.h"

@interface myLaunchClass : NSObject
-(BOOL) LaunchApp:(CAtlString)exePath;
@end

myLaunchClass.mm

@import "myLaunchClass.h"

@implementation myLaunchClass
-(BOOL) LaunchApp:(CAtlString)exePath
{
    ....
    return someCondition;
}
@end

从那里编译好。我将 .mm 文件添加到构建阶段中的目标中,并将标题位置添加到构建设置中的标题搜索路径中。

当我在 .cpp 文件 ( #include "myinterface.h") 中包含头文件时,我没有错误。但是,当我调用函数 ( ::LaunchApp(exePath);) 时,出现链接器错误。

错误

Undefined symbols for architecture i386:
  "LaunchApp(CAtlString)", referenced from:
      myCppFile::myCppFunction() const in myCppFile.o
ld: symbol(s) not found for architecture i386

有任何想法吗?我认为这对于 Mac 开发人员来说一定是一个明显的错误,但我对 Mac 编程还是有点陌生​​。任何帮助表示赞赏。

4

1 回答 1

1

Objective-C++ 不以这种方式互操作。-(BOOL)LaunchApp:(CAtlString)exePath在 Objective-C 类上声明一个实例方法。该方法只能从 Objective-C(即 .m、.mm)文件中调用,如果方法签名包含 C++ 类型(就像这里一样),那么它只能从 Objective-C++ (.mm) 中调用文件。此外,-(BOOL)LaunchApp:(CAtlString)exePath是一个实例方法,您似乎正在调用它,就好像它是一个 C++ 静态/类方法一样,这也不起作用。

如果您想包装您的 Objective-C 类以使其可供直接 C++ 消费者使用,您必须执行以下操作:

MyLaunchClass.h

#if __cplusplus
#import <string>
#endif

@interface MyLaunchClass : NSObject

#if __cplusplus
- (BOOL)launchApp: (std::string)str;
#endif

@end

#if __cplusplus

struct WrappedMyLaunchClass
{
    MyLaunchClass* mImpl;

    WrappedMyLaunchClass() : mImpl([[MyLaunchClass alloc] init]) { };

    ~WrappedMyLaunchClass() { mImpl = nil; }; // Assuming ARC here. for non-ARC, [mImpl release]

    bool LaunchApp(std::string str)
    {
        return !![mImpl launchApp:str];
    }
};

#endif

MyLaunchClass.mm

#import "MyLaunchClass.h"
#import <string>

@implementation MyLaunchClass

- (BOOL)launchApp: (std::string)str
{
    NSLog(@"%s", str.c_str());
    return YES;
}

@end

SomeOtherFile.cpp

void someOtherFunction()
{
    WrappedMyLaunchClass x;
    x.LaunchApp("foobar");
}

总之,您高估了 C++ 和 Objective-C++ 的互操作性。您可以将 Objective-C++ 视为“Objective-C,增加了具有 C++ 类型变量的能力和调用 C++ 代码的能力”,而不是“声明 C++ 类型的替代语法”。

买者自负!:这大大简化了将 Objective-C 对象有意义地包装在 C++ 对象中所涉及的内容。C++ 的按值/按引用语义与Objective -C 的语义完全不同,如果 C++ 对象曾经按值传递(即通过复制构造函数)等,像这样的幼稚实现将遇到各种问题。我提供该示例只是为了说明为什么您尝试的操作不起作用,而不是作为将 Objective-C 对象包装在 C++ 对象中的某种通用代码。

于 2013-09-25T14:30:13.710 回答