Использование статических библиотек C / C ++ из приложений iPhone ObjectiveC

Возможно ли иметь API статической библиотеки C, которая использует C ++ для внутреннего использования и скрывает это от пользователей библиотеки?

Я написал переносимую библиотеку C ++, которую я хотел бы статически связать с приложением iPhone.

Я создал проект XCode, используя шаблон «статической библиотеки» Max OS X, и скопировал исходный код, а также написал C-ваппер (для обработки исключений), используя (extern «C»).

Я пытаюсь использовать сгенерированную библиотеку (файл .a) в другом приложении Cocoa iPhone.

Все работает хорошо, если я использую расширения (.mm) в вызывающем файле ObjectiveC и (.cpp) в классе реализации в библиотеке.

Но я получаю неразрешенные символы при связывании, когда пытаюсь изменить файл оболочки на расширение (.c), даже если все файлы функций оболочки являются только Си-функциями.

Просто потому, что C ++ используется внутри библиотеки, означает ли это, что внешне он все еще должен рассматриваться как программа C ++. Разве нет в любом случае для обеспечения этой абстракции?

Редактировать: Спасибо за ответы,

Я использовал extern «C», я просто не был уверен в том, какие конфигурации нужны в вызывающем проекте. то есть. если предполагаемый вызов потребует знать, использует ли он C ++ или может быть невежественным, и думать, что это чисто библиотека C.

Казалось бы, я не могу, и я должен использовать (.mm) файлы на моих классах ObjectiveC.

 Jason Coco18 дек. 2008 г., 06:32
Вы объявляете свои функции библиотеки C с помощью extern "C"?
 Akusete18 дек. 2008 г., 07:01
Моя ошибка, я не осознавал, что ты это удалил.
 Jason Coco18 дек. 2008 г., 07:00
Akusete, твой вопрос на самом деле не о Objective-C ... он о C / C ++ и проблемах с инструментами. Я думаю, что ваша проблема в том, что вы не получаете поддержку C ++, потому что в Xcode вы связываете приложение C. Не добавляйте теги к Obj-C, если в Q нет ничего конкретно об Obj-C

Ответы на вопрос(4)

Решение Вопроса

Это слишком сложно сделать в комментариях, поэтому я просто собираюсь показать вам, какие проблемы с ссылками у вас возникают. Когда XCode встречает файлы, он использует правила сборки, основанные на суффиксе, чтобы решить, какой компилятор использовать. По умолчанию gcc связывает файлы со стандартной библиотекой C, но не связывает со стандартной библиотекой C ++. Архивные файлы (статические библиотеки) вообще не имеют разрешения на связывание. В основном это архив объектных файлов, которыедолжны быть связаны, Поскольку в вашем проекте нет файлов .mm или .cpp, g ++ никогда не вызывается, а ваши файлы никогда не связаны со стандартными библиотеками. Чтобы исправить это, просто добавьте стандартные библиотеки C ++ к вашим другим флагам компоновщика в вашем проекте XCode или просто добавьте их в предопределенную опцию других флагов как -l (например, -lstdc ++).

Вот быстрая демонстрация:

stw.h:

#ifdef __cplusplus
extern "C"
#endif
void show_the_world(void);

stw.cpp:

#include <iostream>
#include "stw.h"
using namespace std;

extern "C" void show_the_world() {
  cout << "Hello, world!\n";
}

Постройте библиотеку:

$ g++ -c stw.cpp -o stw.cpp -O0 -g
$ ar rcs stw.a stw.o

Использование библиотеки из приложения C:

myapp.c:

#include "stw.h"

int main() {
  show_the_world();
  return 0;
}

Сборка приложения C:

$ gcc -o myapp myapp.c stw.a -lstdc++ -g -O0
$ ./myapp
Hello, world!
$

Если вы попытаетесь скомпилировать без -lstdc ++, вы получите все нерешенные проблемы, потому что компилятор C не имеет абсолютно никакого представления о том, что он должен ссылаться на среду выполнения C ++ (и почему это так, верно!?!?), Поэтому вы должны добавить это вручную. Другой вариант, который у вас есть, это изменить правило сборки для вашего проекта ... вместо того, чтобы Xcode использовал gcc для сборки файлов .c и .m, скажите ему использовать g ++, и ваши проблемы будут решены.

 Batgar01 апр. 2010 г., 20:10
Это спасло мой бекон, когда я включил библиотеки FMOD в мой прямой проект Objective-C. Нужно включить -lstdc ++, чтобы избавиться от ошибок ссылок.
 Jason Coco18 дек. 2008 г., 07:40
ах, ты совсем не раздражаешь :) просто все делалось в 300 комментариях персонажа было ...
 Akusete18 дек. 2008 г., 07:30
Спасибо за вашу помощь, мои извинения за раздражение. Я несколько не знаю, как работает среда выполнения C ++, и раньше всегда использовал g ++ или VC ++.

Вы должны объявить функции, которые вы хотите видетьextern "C", Их подписи должны быть C-совместимыми, а содержимое - нет (например, вы можете обращаться к объектам C ++, но не можете передавать их напрямую; указатели в порядке). Символы будут видны любой C-совместимой среде.

РЕДАКТИРОВАТЬ: И скомпилировать его как исходный файл C ++, C не имеет понятия языковой связи. Есть пара других проблем с языковой связью (например, тот факт, что всеextern "C" функции с одинаковыми именами являются одной и той же функцией, независимо от пространства имен).

EDIT2: в шапке вы можете проверить макрос__cplusplusи используйте это для установки для C ++ и других языков соответственно (потому что C ++ потребуетextern "C" декларации и другие языки, вероятно, будут жаловаться на них).

 Akusete18 дек. 2008 г., 06:49
Спасибо, «скомпилируйте его как исходный файл C ++» означает, что мне все еще понадобится (.mm) файл Objective C, чтобы правильно его использовать? «C не имеет понятия о языковой связи». Я думаю, это означает, что если у меня есть C ++ где-нибудь внутри библиотеки, все это должно быть скомпилировано как C ++.

В основном, когда вы компилируете функции C с помощью компилятора C ++, он обрабатывает имена функций и использует ABI C ++.

Когда вы используете расширение * .cpp или * .mm, вы используете компилятор C ++.

То, что вы хотите сделать, это заставить компилятор генерировать функции C с именами, не являющимися искажениями, и использовать C ABI.

Вы можете сделать это одним из следующих способов:

Компилировать с помощью компилятора C.Скомпилируйте с помощью компилятора C ++, но убедитесь, что вы используете префикс объявления функций с помощью extern "C"

Любимый способ настроить файл заголовка, чтобы один и тот же файл мог быть включен из исходных файлов C и C ++, это:

#ifndef HEADER_GUARD_1_H
#define HEADER_GUARD_1_H

#ifdef __cplusplus
extern "C" {
#endif

// Declare C function interface here.
int myFunc(int x,char*);

#ifdef __cplusplus
}
#endif

#endif 
 Martin York18 дек. 2008 г., 17:37
.Mm просто заставляет его использовать компилятор C ++, а не компилятор C. Цель C - просто оболочка этих языков (я не имею в виду буквально).
 William Denniss04 июл. 2010 г., 18:32
спасибо за советы!
 Akusete18 дек. 2008 г., 06:52
Спасибо, я понимаю использование extern "C", библиотека в настоящее время работает для C / C ++ / C # (используя pinvoke), на платформах win32 windowsCE и linux. Однако я не уверен, нужно ли мне использовать (.mm) в кодеjectiveC, если мой интерфейс был C.

спасибо за такую ​​хорошую дискуссию.

что я сделал, это:

1) Я создал статический lib, используя опцию cocaotouch static lib. В этом у меня есть c / c ++ / obj-c все смешать. тем не менее, мой экспорт только классы obj-c. Фактически я использовал objc- to C ++.

2) Затем я создал приложение для iphone в X-Code Proj. Я добавил другие ссылки, помечает мое имя библиотеки (-lxyz) // мое имя библиотеки libxyz.a Я добавил путь поиска lib, путь поиска заголовка

3) потом я скомпилировал. Я получил ошибки. Говорят, новый оператор, оператор удаления не найден.

3) затем, кроме моего приложения applelegate, контроллера представления, я добавил фиктивную cpp (.h, .cpp) ... atestdummy.h atestdummy.cpp

4) потом строю заново ...

вот это сработало.

Так что - все предложения, которые они давали ранее, работали на меня. основная причина, если ваше приложение не увидит .cpp файл .mm файл с кодом cpp, связанный не будет использовать g ++.

Спасибо всем. Я прочитал выше и решил мою проблему.

ребята, вы можете поделиться.

Ваш ответ на вопрос