Objective-C Yerine Kakao ile C ++ Kullanılsın mı?


122

Apple, Carbon 64-bit yetenekli hale getirmediği için C ++ ve Cocoa çerçevelerini kullanan uygulamalar yazmak istiyorum. C ++, Linux ve Windows'taki uygulamasında oldukça hoş görünüyor, ancak Mac OS X'te Apple'a özgü ek kod parçalarına ihtiyaç var gibi görünüyor (bir Obj-C paketleyicisi gibi). Görünüşe göre Apple, geliştiricileri C ++ yerine Objective-C ile yazmaya zorluyor, ancak yanılıyor olabilirim.

Mac'te kod yazmak için çapraz platformda tutması kolay bir yol bulmaya çalışıyorum. Linux / Windows için C ++ ile kod yazmak ve ardından Objective-C'de büyük bölümleri yeniden yazmak zorunda olmak çok verimsiz olacaktır.

C ++ ile kod yazmanın gelecekte desteklenecek ve Xcode'da desteklenecek bir yolu var mı? Ayrıca, bu mümkünse, Xcode'da C ++ ve Objective-C'yi nasıl karıştırırım? Teşekkürler.

Yanıtlar:


110

Bir Cocoa uygulamasını tamamen C ++ ile yazamazsınız. Kakao, Anahtar-Değer Bağlamaları, delegeler (Kakao stili) ve hedef eylem modeli gibi temel teknolojilerinin çoğu için Objective-C'nin geç bağlama yeteneklerine büyük ölçüde güvenir. Geç bağlama gereksinimleri , Cocoa API'sini C ++ ⁱ gibi derleme zamanına bağlı, tiplenmiş bir dilde uygulamayı çok zorlaştırır. Elbette, OS X üzerinde çalışan saf bir C ++ uygulaması yazabilirsiniz. Sadece Cocoa API'lerini kullanamaz.

Bu nedenle, diğer platformlardaki C ++ uygulamaları ile Cocoa tabanlı uygulamanız arasında kod paylaşmak istiyorsanız iki seçeneğiniz vardır. Birincisi, model katmanını C ++ 'da ve GUI'yi Cocoa'da yazmaktır. Bu, Mathematica dahil bazı çok büyük uygulamaların kullandığı yaygın bir yaklaşımdır . C ++ kodunuz değiştirilmeden bırakılabilir (OS X'te C ++ yazmak veya derlemek için "korkak" elma uzantılarına ihtiyacınız yoktur). Denetleyici katmanınız büyük olasılıkla Objective-C ++ (belki de bahsettiğiniz "funky" Apple uzantısı) kullanacaktır. Objective-C ++, tıpkı Objective-C'nin C'nin bir üst kümesi olması gibi, C ++ 'nın bir üst kümesidir [some-objc-object callMethod];. Tersine, C ++ işlevlerini ObjC kodunun içinden şu şekilde çağırabilirsiniz:

@interface MyClass {
    MyCPPClass *cppInstance;
}
@end

@implementation MyClass
- (id)init {
    if(self = [super init]) {
        cppInstance = new MyCPPClass();
    }
    return self;
}
- (void) dealloc {
    if(cppInstance != NULL) delete cppInstance;
    [super dealloc];
}
- (void)callCpp {
    cppInstance->SomeMethod();
}
@end

Objective-C ++ hakkında daha fazla bilgiyi Objective-C dil kılavuzunda bulabilirsiniz . Görünüm katmanı daha sonra saf Objective-C olabilir.

İkinci seçenek, platformlar arası bir C ++ araç takımı kullanmaktır. Qtaraç seti faturaya uyabilir. Çapraz platform araç kitleri, tüm görünüm ve his ayrıntılarını tam olarak doğru anlamadıkları ve Mac kullanıcıları, Mac uygulamalarının kullanıcı arayüzünde iyi bir görünüm bekledikleri için genellikle Mac kullanıcıları tarafından hor görülüyor. Ancak Qt, şaşırtıcı derecede iyi bir iş çıkarır ve hedef kitleye ve uygulamanızın kullanımına bağlı olarak yeterince iyi olabilir. Ek olarak, Core Animation ve bazı QuickTime işlevleri gibi OS X'e özgü bazı teknolojileri kaybedeceksiniz, ancak Qt API'de yaklaşık değişiklikler var. Sizin de belirttiğiniz gibi, Carbon 64 bit'e taşınmayacak. Qt, Carbon API'lerinde uygulandığından, Trolltech / Nokia, Qt'yi 64-bit uyumlu hale getirmek için Cocoa API'ye taşımak zorunda kaldı. Anladığım kadarıyla, Qt'nin bir sonraki relase (şu anda sürüm aday) bu geçişi tamamlar ve OS X'te 64-bit uyumludur. C ++ ve Cocoa API'lerini entegre etmekle ilgileniyorsanız, Qt 4.5'in kaynağına bir göz atmak isteyebilirsiniz.


ⁱ Apple bir süredir Cocoa API'yi Java için kullanılabilir hale getirdi, ancak köprü kapsamlı bir el ayarı gerektirdi ve yukarıda açıklanan Anahtar-Değer Bağlamaları gibi daha gelişmiş teknolojileri kaldıramadı. Şu anda dinamik olarak yazılmış, Python, Ruby, vb. Gibi çalışma zamanına bağlı diller, Objective-C olmadan bir Cocoa uygulaması yazmak için tek gerçek seçenektir (elbette bu köprüler başlık altında Objective-C kullanıyor).


Şu anda küçük Ogre3D uygulamamı taşımaya çalışıyorum, ÇOK acı verici görünüyor. Apple herkesi Objc'ye dönüştürmeye mi çalışıyor yoksa bu gerçekten bir özellik mi?
jokoon

68

Kulağa aptalca gelebilir, ama aslında Mac OS X için GUI oluşturmak için saf C ++ kodu yazabiliriz, ancak Cocoa çerçevesine bağlanmalıyız.

/*
 * test1.cpp
 * This program shows how to access Cocoa GUI from pure C/C++
 * and build a truly functional GUI application (although very simple).
 * 
 * Compile using:
 *   g++ -framework Cocoa -o test1 test1.cpp
 *
 * that will output 'test1' binary.
 */


#include <CoreFoundation/CoreFoundation.h>
#include <objc/objc.h>
#include <objc/objc-runtime.h>
#include <iostream>

extern "C" int NSRunAlertPanel(CFStringRef strTitle, CFStringRef strMsg,
                               CFStringRef strButton1, CFStringRef strButton2, 
                               CFStringRef strButton3, ...);


int main(int argc, char** argv)
{
    id app = NULL;
    id pool = (id)objc_getClass("NSAutoreleasePool");
    if (!pool)
    {
        std::cerr << "Unable to get NSAutoreleasePool!\nAborting\n";
        return -1;
    }
    pool = objc_msgSend(pool, sel_registerName("alloc"));
    if (!pool)
    {
        std::cerr << "Unable to create NSAutoreleasePool...\nAborting...\n";
        return -1;
    }
    pool = objc_msgSend(pool, sel_registerName("init"));

    app = objc_msgSend((id)objc_getClass("NSApplication"),
                       sel_registerName("sharedApplication"));

    NSRunAlertPanel(CFSTR("Testing"),
                    CFSTR("This is a simple test to display NSAlertPanel."),
                    CFSTR("OK"), NULL, NULL);

    objc_msgSend(pool, sel_registerName("release"));
    return 0;
}

17
Bu harika. Daha karmaşık örnekler var mı? Örneğin, bir NSWindow mu açıyorsunuz?
imallett

test1.cpp: 'int main (int, char **)' işlevinde: test1.cpp: 26: 48: hata: başlatma kimliğinde 'Class {aka objc_class *}' 'id {aka objc_object *}' olarak dönüştürülemiyor pool = objc_getClass ("NSAutoreleasePool"); ^ test1.cpp: 41: 61: hata: '1' bağımsız değişkeni için 'Sınıf {aka objc_class *}', 'objc_object *}' olarak 'objc_object * objc_msgSend (id, SEL, ...)' dönüştürülemiyor sel_registerName ( "sharedApplication")); ^
Jichao

6
İle Clang uyumluluğu bkz @Jichao iç Objective-C tipleri - düzeltme basit: yerine objc_getClassile(id)objc_getClass
Dmitry Isaev

Örneğin ayarlamak için std :: string'i nasıl kullanabilirim. uyarı panelinin başlığı? ... Ben c_str () ve benzeri kullanılarak denedim ama hiçbiri işe yaramadı
mdre

1
Bu artık macOS Catalina'da
derlenmiyor

18

Evet, sadece C ++ kullanabilir (yani * .cpp dosyalarında yazarak) ve hatta C ++ ve Objective-C'yi * .mm dosyalarının içinde karıştırabilirsiniz (standart Objective-C kodu * .m dosyalarında saklanır).

Elbette, kullanıcı arayüzünüz için hala Objective-C kullanmanız ve C ++ nesneleriniz için Objective-C sarmalayıcılar oluşturmanız gerekir. Başka bir seçenek geçiş etmektir Qt ve sonraki sürümü 4.5 ile LGPL altında çıkacak - destekleri, Windows, Mac OS X ve Linux bir C ++ Framework.


23
Qt kullanırsanız, uygulamanızın berbat olacağını unutmayın. Qt tabanlı uygulamalar, yerel Mac uygulamaları gibi görünmez ve hissedilmez. (Bir örnek için, Google Earth'e bakın.)
Peter Hosey

15
Peter: Bu hiç doğru değil. Qt tabanlı uygulamalar, yerel Mac uygulamalarıyla aynı görünebilir ve hissedilebilir, yalnızca her platformda yerel bir GUI yazmaktan çok daha kolay bir şey olan her platform için ince ayar yapmanız gerekir.
Mike McQuaid

12
Mike, yanlış bilgilendirilmişsin. Mac'teki Qt tabanlı uygulamalar diğer eksikliklerinin yanı sıra yerel kontrolleri hiç kullanmaz ve Qt kitaplığı çizimin tamamını kendisi yapar. Bu, Qt uygulamalarının 2D oluşturma için herhangi bir donanım hızlandırması almadığı, Apple'ın standart kontrollerde yaptığı UI değişiklikleriyle senkronize kalmadığı ve bir Qt uygulamasının siz bunları yeniden icat etmedikçe ADA uyumluluğu veya komut dosyası sağlayamayacağı anlamına gelir. kendiniz tekerlekler. Başka bir deyişle, Mac'te bir Qt uygulaması göndermeye ÇALIŞMAYIN. Google bundan kurtulabilir: yapamazsınız.
NSResponder 01

13
Yerel kontrolleri kullanıyorlar, bu yüzden Qt'nin Kakao ve Karbon versiyonu var. Başka sorunları var, ancak birçok kişi Mac'te Qt uygulamaları gönderiyor ve iyi çalışıyorlar (ve biraz ince ayarlarla mükemmel bir şekilde).
Mike McQuaid

2
Yalnızca yerel kontrolün kullanılması, yerel uygulamalar gibi görüneceği ve hissedileceği anlamına gelmez . Yerel bir his yaratan şey , her işletim sisteminin farkıdır . Uygulamanızı belirli bir platformda hissedilecek şekilde ayarlarsanız, başka bir platformda yerel olarak hissedilmeyecektir. Ve bir kez soyutlanmış katmanda küçük davranışların ince ayarı, bunu yerel katmanda yapmaktan her zaman daha zordur.
eonil

9

Evet onları karıştırabilirsiniz.

Doğrudan GUI nesneleriniz üzerinde çalışmak ve onlardan bildirim almak için Objective-C'yi kullanmanız gerekir.

Bu Objective-C nesneleri, saf Objective-C .m dosyaları yerine .mm dosyalarına koyarsanız doğrudan C ++ mantığını çağırabilir. Objective-C ++ 'ı belirtmek için büyük harfli .M kullanılmasını öneren (çok) eski tavsiyeler görebileceğinizi unutmayın, ancak bu çok kesintili ve derleyicinin yanı sıra sizi de şaşırtabilir.

Her bir C ++ nesnesini sarmalamanız gerekmez, ancak Objective-C kodunuzun bunlara işaretçiler içermesi gerekir.

Apple artık bunun nasıl yapılacağını gösteren herhangi bir örnek yayınlamıyor.

Realm'de sunulan Peter Steinberger'in harika bir videosu var [Amaç] C ++: Neler Yanlış Gidebilir? Hala Objective-C ++ kullanan herkese şiddetle tavsiye ederim ve transkripte hızlıca göz atabilirsiniz.


@SteveS bağlantınız da koptu
fferri

@fferi - Yukarıdaki Steinberger bağlantısı düzeltildi. Karbon Kakao Entegrasyonu 2007'den itibaren developer.apple.com sitesinden alınmıştır, Apple bunu kaldırdı. Bu, GERÇEKTEN Carbon API'leri kullanarak yeni kod yazmamanız gerektiğini gösterir. Bu noktada, Carbon kullanarak mevcut kodu korumak bile risklidir. Bu sorunun ya yönelik kabul edilen cevaba bakın bu bir C ++ / Objective C karıştırmak gerekirse, ancak Karbon kullanarak edilmemelidir. Burada şöyle
yazıyordu

4

Sadece sade vanilya C ++ kullanmak istiyorsanız, bu kesinlikle desteklenir ve gerçekten diğer platformlardan farklı değildir. Xcode'un Dosya> Yeni Proje> Komut Satırı Yardımcı Programı> C ++ Aracı altında bunun için bir şablonu bile vardır. Ayrıca, bir dizi popüler açık kaynak kitaplığı (libcurl, libxml2, sqlite, vb.) OS X ile birlikte gelir ve dinamik bağlantı için kullanılabilir. İstemiyorsanız Kakao veya Apple'a özgü herhangi bir şey kullanmanız gerekmez.

Cocoa'yı uygulamanızın belirli bölümlerinde kullanmak istiyorsanız, Objective-C ++ 'ya bir göz atın . C ++ ve Objective-C'yi aynı dosyada, bir .mm uzantısı vererek veya Xcode'da dosyaya sağ tıklayıp Bilgi Al> Genel'i seçip ardından Dosya Türünü sourcecode.cpp.objcpp olarak değiştirerek karıştırabilirsiniz. İkinci seçenek, Mac'e özgü bir #ifdef içinde Objective-C'yi kullanmak istediğiniz bir .cpp dosyanız varsa kullanışlıdır.


1
BTW, (gerçekten kullanışlı) C ++ şablonu, Xcode'un son sürümleriyle (4.x ve 5.x) gitti
Jay

1

Bu eski bir soru olsa da ...

Ben var bazı Kakao sınıfların C ++ sarmalayıcı yapmaya çalıştı .

Oldukça güzel bir deneyimdi. C ++, Objective-C'den daha iyi tür güvenliği sağladı ve daha az kod yazmamı sağladı. Ancak derleme süresi ve bellek güvenliği daha kötüdür. Mümkün, ancak bazı dinamik tabanlı özelliklerin kullanımı kolay değildi. Bununla C ++ üzerinde uğraşmanın mantıklı olmadığını düşünüyorum.

Her neyse projem Swift'in duyurusu nedeniyle nihayet terk edildi. İlk başta C ++ kullanmak istememin tüm nedenlerini temizledi ve daha fazlasını ve daha iyisini sağlıyor.


0

Tamamen grafiksel bir uygulama yazıyorsanız, yani her şeyi kod kullanarak çiziyorsanız , openFrameworks'ü düşünün . C / C ++ üzerine inşa edilmiş açık kaynaklı bir grafik programlama dilidir. Bu sahiptir addons insanların dilini uzatmak için izin verir. Iphone için bir eklentileri var . İPhone ve iPod touch için uygulamaları derlemenize yardımcı olacak kitaplık ve XCode projeleriyle birlikte geldiğine inanıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.