Objective-C++调用C或C++函数

3
作为这里发布的大多数其他Objective-C问题一样,我也是ObjC的新手。我正在编写一个基于我们现有的用C#和C++编写的产品的iOS应用程序。我已经在C++中编写了一个完整的库,希望能够直接在iOS设备上使用它,只需提供一些#ifdef来阻止必要的代码。例如,我有一个完整的C++类,用于使用Winsock进行HTTP请求。因此,为了能够将API的这一部分转换为Obj-C,我希望我可以编写一些简单的Obj-C类,使用NSURL、NSString等内置库发送和接收数据。但是,我似乎无法将事物传递到我在C++中编写的Obj-C(++ )方法中。在我花费太多时间浪费在无用的事情上之前,我想在这里确定是否可能。据我所知,Obj-C的构建/设计方式实际上都是C代码,因此合并两种语言并不困难。我错了吗?例如,我能做到这样吗?
class NameValueCollection {
  NameValueCollection() { };
  NameValueCollection(std::string key, std::string value);
  ~NameValueCollection();
...
};

然后,在Obj-C中(实际上是Obj-C++,我已经更改了文件编译的语言...)

-(BOOL)initWithValues:(NameValueCollection*) nvc result:(NSString*)result;

我尝试这样做是否太过分了?如果是,那么有两个替代方案之一可行吗?
从C++类/对象/方法中调用ObjC++方法,或者在Obj-C++方法中调用C++方法?
我必须承认,我有点假设最后一个替代方案会起作用,而且我非常确定第一个替代方案会起作用,但如果第一个选项可行,则最好。有人能提供深入的见解吗?我是否正确地尝试使用Obj-C++实现这一点,或者只能在Obj-C中调用C函数而不是C++方法,以便我可以在iOS应用程序中直接使用我们预定义(和预调试)的对象,只需在关键时刻用Obj-C++代码替换即可...
我是C++库代码的原始作者,因此如果需要,我可以对其进行更改,甚至可以利用预处理器,但显然,我需要在C++端更改的代码越少越好!:) 我没有将C++代码构建为Dynlib或任何类似的东西,我只是在源控制级别上共享文件。但是,我愿意接受任何可以使整个事情按照我尝试的方式工作的想法。
提前感谢大家...

1
什么出了问题?你可以很好地从Objective-C调用纯C/C++函数。 - Adam Rosenfield
你只需要记住把“粘合”模块命名为“.mm”。 - Hot Licks
你所编写的代码应该能够正常工作。需要注意的是,要使用C++代码,你需要使用.mm扩展名来表示文件是一个Objective-C++文件。但是需要注意的是,Winsock调用将无法工作,它们需要被#ifdef掉并替换为标准Unix sockets调用或更高级别的本地网络API。 - wadesworld
1
我发现的两个重要问题是:(1)对于非POD类,应将它们包装在结构体中,并将结构体作为不透明类型传递;(2)在边界处处理所有异常。不要让Objective-C异常传递到C++,也不要让C++异常传递到Objective-C。Objective-C++可以让你混合使用这两种语言,但我只将其用作非常薄的接口。 - sfstewman
Adam和sfstewman,我+1了你们的评论,因为你们是正确的...现在我在ObjC ++方面更有经验,我知道要注意的事情等等。也许我学到的最大的一件事是必须使用C链接。因此,现在我的跨平台库源代码都包括一个#ifdef,如果我们正在编译Obj-C,则会extern“C”我的.h文件,无论情况如何。 - LarryF
1个回答

0

我知道在obj-c++中使用c++类/方法是完全可能的。我一直在使用BulletPhysics库进行iOS开发,它是用c++编写的,我可以毫无问题地使用其功能。我认为你需要做的事情是将库的源文件添加到项目中。对于BulletPhysics,将库外部编译为框架,然后导入框架对我来说并没有正确地工作。所以我做的是将库的源文件添加到项目中,然后只需#include我需要的头文件,然后xcode会负责编译库和我的源代码,然后它就可以工作了。

只需确保使用库头文件的文件的扩展名为.mm。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接