Использование общего кода C ++ / STL с Objective-C ++ - PullRequest
3 голосов
/ 05 июня 2009

У меня много общего кода C ++, который я хотел бы использовать в своем приложении для iPhone. Я добавил файлы .cpp и .h в свой проект Xcode и использовал классы в своем коде Objective-C ++. Проект компилируется нормально с 0 ошибками или предупреждениями.

Однако, когда я запускаю его в симуляторе, я получаю следующую ошибку при попытке получить доступ к методу STL в моем коде Objective-C (например, .c_str()):

Program received signal:  “EXC_BAD_ACCESS”.

Unable to disassemble std::string::c_str.

Вот пример кода, который вызывает ошибку:

[name setText:[[NSString alloc] initWithCString:myCPlusPlusObject->cppname.c_str()]];

, где name - это объект NSTextField, а cppname - член std :: string myCPlusPlusObject.

Правильно ли я поступаю? Есть ли лучший способ использовать загруженные STL классы C ++ в Objective-C ++? Я бы хотел, чтобы обычные файлы C ++ не затрагивались, если это возможно, чтобы избежать необходимости поддерживать код в двух местах.

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 05 июня 2009

Убедитесь, что строка не пуста, прежде чем передавать ее в функцию initWithCString.

Также используемая вами функция устарела, используйте вместо нее .

2 голосов
/ 06 июня 2009

Обратите внимание, что эта строка кода:

[name setText:[[NSString alloc] initWithCString:myCPlusPlusObject->cppname.c_str()]];

утечка созданной строки.

Вернитесь и прочитайте правила управления памятью на http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html.

Основная проблема заключается в том, что вы выделили строку, поэтому вы взяли на себя ответственность за нее, а затем никогда не отпускаете ее. Вам следует выполнить одно из следующих действий:

[name setText:[[[NSString alloc] initWithCString:myCPlusPlusObject->cppname.c_str() encoding:NSUTF8StringEncoding] autorelease]];

или

NSString* myCPlusPlusString = [[NSString alloc] initWithCString:myCPlusPlusObject->cppname.c_str() encoding:NSUTF8StringEncoding];
[name setText:myCPlusPlusString];
[myCPlusPlusString release];

или

[name setText:[NSString stringWithCString:myCPlusPlusObject->cppname.c_str() encoding:NSUTF8StringEncoding]];

Последнее является лучшим с точки зрения простоты кода. Средний показатель является лучшим с точки зрения использования памяти, что часто является проблемой для iPhone.

Первый, скорее всего, идентичен последнему - я говорю «вероятно», потому что нет гарантии, что stringWithCString возвращает объект с автоматическим освобождением. Возможно, это так, но независимо от того, волнует это или нет, все, что вам важно, это то, что вы не вступаете во владение строкой, потому что имя метода не начинается с «alloc» или «new» или содержит «copy» и поэтому вы не несете ответственности за его освобождение.

1 голос
/ 05 июня 2009

Я бы попробовал это:

if (myCPlusPlusObject)
{
    [name setText:[[NSString alloc] initWithUTF8String:myCPlusPlusObject->cppname.c_str()]];
}
else
{
    [name setText:@"Plop: Bad myCPlusPlusObject"];
}

Вероятно, проблема с указателем NULL, поскольку std :: String всегда будет правильно инициализироваться, если он существует, а метод c_str () будет возвращать завершенную строку '\ 0', даже если строка пуста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...