Share via


Visual Studio'da Python için C++ uzantısı oluşturma

Bu makalede, bir hiperbolik tanjant hesaplamak ve Python kodundan çağırmak üzere CPython için bir C++ uzantısı modülü oluşturacaksınız. Yordam, C++ dilinde aynı yordamı uygulamanın göreli performans kazancını göstermek için önce Python'da uygulanır.

C++ (veya C) dilinde yazılan kod modülleri genellikle Python yorumlayıcının özelliklerini genişletmek için kullanılır. Üç birincil uzantı modülü türü vardır:

  • Hızlandırıcı modülleri: Hızlandırılmış performansı etkinleştirin. Python yorumlanmış bir dil olduğundan, daha yüksek performans için C++ dilinde bir hızlandırıcı modülü yazabilirsiniz.
  • Sarmalayıcı modülleri: Mevcut C/C++ arabirimlerini Python kodunda kullanıma sunma veya Python'dan kullanımı kolay python benzeri bir API'yi kullanıma sunma.
  • Düşük düzeyli sistem erişim modülleri: Çalışma zamanının, işletim sisteminin veya temel alınan donanımın CPython alt düzey özelliklerine ulaşmak için sistem erişim modülleri oluşturun.

Bu makalede, C++ uzantısı modülünü Python'da kullanılabilir hale getirmenin iki yolu gösterilmektedir:

  • Python belgelerinde açıklandığı gibi standart CPython uzantıları kullanın.
  • Basitliği nedeniyle C++11 için önerdiğimiz PyBind11 kullanın. Uyumluluğu sağlamak için Python'ın en son sürümlerinden biriyle çalıştığından emin olun.

Bu izlenecek yol için tamamlanmış örnek, GitHub'da python-samples-vs-cpp-extension adresinde bulunabilir.

Önkoşullar

  • Python geliştirme iş yükü yüklü visual studio 2017 veya üzeri. İş yükü, yerel uzantılar için gerekli C++ iş yükünü ve araç kümelerini ekleyen Python yerel geliştirme araçlarını içerir.

    Screenshot of a list of Python development options, highlighting the Python native development tools option.

    Yükleme seçenekleri hakkında daha fazla bilgi için bkz . Visual Studio için Python desteğini yükleme.

    Not

    Veri bilimi ve analitik uygulamalar iş yükünü yüklediğinizde, Python ve Python yerel geliştirme araçları seçeneği varsayılan olarak yüklenir.

  • Python'ı ayrı olarak yüklerseniz, Python yükleyicisindeki Gelişmiş Seçenekler'in altında Hata ayıklama simgelerini indir'i seçtiğinizden emin olun. Bu seçenek, Python kodunuzla yerel kodunuz arasında karma mod hata ayıklamayı kullanmanız için gereklidir.

Python uygulamasını oluşturma

Python uygulamasını oluşturmak için bu adımları izleyin.

  1. Visual Studio'da Dosya>Yeni Proje'yi seçerek yeni>bir Python projesi oluşturun.

  2. Yeni proje oluştur iletişim kutusunda Python'ı arayın. Python Uygulaması şablonunu seçin ve İleri'yi seçin.

  3. Bir Proje adı ve Konum girin ve Oluştur'u seçin.

    Visual Studio yeni projeyi oluşturur. Proje Çözüm Gezgini açılır ve proje dosyası (.py) kod düzenleyicisinde açılır.

  4. .py dosyasına aşağıdaki kodu yapıştırın. Python düzenleme özelliklerinden bazılarını deneyimlemek için kodu el ile girmeyi deneyin.

    Bu kod matematik kitaplığını kullanmadan hiperbolik tanjant hesaplar ve Python yerel uzantılarıyla daha sonra hızlandırdığınız şey budur.

    İpucu

    C++ dilinde yeniden yazmadan önce kodunuzu saf Python'da yazın. Bu şekilde, yerel Python kodunuzun doğru olduğundan emin olmak için daha kolay kontrol edebilirsiniz.

    from random import random
    from time import perf_counter
    
    # Change the value of COUNT according to the speed of your computer.
    # The value should enable the benchmark to complete in approximately 2 seconds.
    COUNT = 500000
    DATA = [(random() - 0.5) * 3 for _ in range(COUNT)]
    
    e = 2.7182818284590452353602874713527
    
    def sinh(x):
        return (1 - (e ** (-2 * x))) / (2 * (e ** -x))
    
    def cosh(x):
        return (1 + (e ** (-2 * x))) / (2 * (e ** -x))
    
    def tanh(x):
        tanh_x = sinh(x) / cosh(x)
        return tanh_x
    
    def test(fn, name):
        start = perf_counter()
        result = fn(DATA)
        duration = perf_counter() - start
        print('{} took {:.3f} seconds\n\n'.format(name, duration))
    
        for d in result:
            assert -1 <= d <= 1, " incorrect values"
    
    if __name__ == "__main__":
        print('Running benchmarks with COUNT = {}'.format(COUNT))
    
        test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d] (Python implementation)')
    
  5. Hata Ayıklama Olmadan Başlat'ı>seçerek programı çalıştırın veya Ctrl+F5 klavye kısayolunu seçin.

    Program çıkışını göstermek için bir komut penceresi açılır.

  6. Çıktıda, karşılaştırma işlemi için bildirilen süreye dikkat edin.

    Bu kılavuzda karşılaştırma işlemi yaklaşık 2 saniye sürmelidir.

  7. Gerektiğinde, karşılaştırmanın COUNT bilgisayarınızda yaklaşık 2 saniye içinde tamamlanmasını sağlamak için koddaki değişkenin değerini ayarlayın.

  8. Programı yeniden çalıştırın ve değiştirilen COUNT değerin yaklaşık 2 saniye içinde karşılaştırma ürettiğini onaylayın.

İpucu

Karşılaştırmaları çalıştırdığınızda her zaman Hata Ayıklama Olmadan Hata Ayıklama>Başlangıç seçeneğini kullanın. Bu yöntem, Visual Studio hata ayıklayıcısında kodu çalıştırdığınızda oluşabilecek ek yükü önlemeye yardımcı olur.

Çekirdek C++ projelerini oluşturma

Superfastcode ve superfastcode2 olmak üzere iki özdeş C++ projesi oluşturmak için bu adımları izleyin. Daha sonra, C++ kodunu Python'da kullanıma açmak için her projede farklı bir yaklaşım kullanırsınız.

  1. Çözüm Gezgini çözüm adına sağ tıklayın ve Yeni Proje Ekle'yi>seçin.

    Visual Studio çözümü hem Python hem de C++ projeleri içerebilir. Bu, Python geliştirmesi için Visual Studio kullanmanın avantajlarından biridir.

  2. Yeni proje ekle iletişim kutusunda Dil filtresini C++ olarak ayarlayın ve Arama kutusuna boş girin.

  3. Proje şablonu sonuçları listesinde Projeyi boşalt'ı ve ardından İleri'yi seçin.

  4. Yeni projenizi yapılandırın iletişim kutusunda Proje adını girin:

    • İlk proje için superfastcode adını girin.
    • İkinci proje için superfastcode2 adını girin.
  5. Oluştur'u belirleyin.

Bu adımları yineleyip iki proje oluşturduğunuzdan emin olun.

İpucu

Alternatif bir yaklaşım, Visual Studio'da Python yerel geliştirme araçları yüklü olduğunda kullanılabilir. Bu makalede açıklanan adımların çoğunu önceden tamamlayan Python Uzantı Modülü şablonuyla başlayabilirsiniz.

Bu makaledeki izlenecek yol için, boş bir projeyle başlamak, uzantı modülünün adım adım nasıl derleneceklerini göstermeye yardımcı olur. İşlemi anladıktan sonra, kendi uzantılarınızı yazarken zaman kazanmak için alternatif şablonu kullanabilirsiniz.

Projeye C++ dosyası ekleme

Ardından, her projeye bir C++ dosyası ekleyin.

  1. Çözüm Gezgini'da projeyi genişletin, Kaynak Dosyalar düğümüne sağ tıklayın ve Yeni Öğe Ekle'yi>seçin.

  2. Dosya şablonları listesinde C++ Dosyası (.cpp) öğesini seçin.

  3. Dosyanın Adını module.cpp olarak girin ve Ekle'yi seçin.

    Önemli

    Dosya adının .cpp uzantısını içerdiğinden emin olun. Visual Studio, C++ proje özellik sayfalarının görüntülenmesini etkinleştirmek için .cpp uzantısına sahip bir dosya arar.

  4. Araç çubuğunda Yapılandırma açılan menüsünü genişletin ve hedef yapılandırma türünüzü seçin:

    Screenshot that shows how to set the target configuration type for the C++ project in Visual Studio.

    • 64 bit Python çalışma zamanı için x64 yapılandırmasını etkinleştirin.
    • 32 bit Python çalışma zamanı için Win32 yapılandırmasını etkinleştirin.

Her iki proje için de bu adımları yineleyi unutmayın.

Proje özelliklerini yapılandırma

Yeni C++ dosyalarına kod eklemeden önce her C++ modül projesinin özelliklerini yapılandırın ve her şeyin çalıştığından emin olmak için yapılandırmaları test edin.

Her modülün hem hata ayıklamahem de sürüm derleme yapılandırmaları için proje özelliklerini ayarlamanız gerekir.

  1. Çözüm Gezgini C++ modül projesine (superfastcode veya superfastcode2) sağ tıklayın ve Özellikler'i seçin.

  2. Modülün hata ayıklama derlemesinin özelliklerini yapılandırın ve ardından yayın derlemesi için aynı özellikleri yapılandırın:

    Proje Özellik Sayfaları iletişim kutusunun üst kısmında aşağıdaki dosya yapılandırma seçeneklerini yapılandırın:

    Screenshot that shows how to set the project build and platform options for the C++ file in Visual Studio.

    1. Yapılandırma için Hata Ayıkla veya Serbest Bırak'ı seçin. (Bu seçenekleri Etkin ön ek.)

    2. Platform için, önceki adımda seçiminize bağlı olarak Etkin (x64) veya Etkin (Win32) seçeneğini belirleyin.

      Not

      Kendi projelerinizi oluşturduğunuzda, hata ayıklama ve sürüm yapılandırmalarını senaryo gereksinimlerinize göre ayrı olarak yapılandırmak istersiniz. Bu alıştırmada, yapılandırmaları CPython'un yayın derlemesini kullanacak şekilde ayarlaacaksınız. Bu yapılandırma, onaylar dahil olmak üzere C++ çalışma zamanının bazı hata ayıklama özelliklerini devre dışı bırakır. CPython hata ayıklama ikili dosyalarının (python_d.exe) kullanılması farklı ayarlar gerektirir.

    3. Aşağıdaki tabloda açıklandığı gibi diğer proje özelliklerini ayarlayın.

      Özellik değerini değiştirmek için özellik alanına bir değer girin. Bazı alanlar için geçerli değeri seçerek seçeneklerden oluşan bir açılan menüyü genişletebilir veya değeri tanımlamaya yardımcı olmak için bir iletişim kutusu açabilirsiniz.

      Sekmedeki değerleri güncelleştirdikten sonra, farklı bir sekmeye geçmeden önce Uygula'yı seçin. Bu eylem, değişikliklerinizin kalmasını sağlamaya yardımcı olur.

      Sekme ve bölüm Özellik Değer
      Yapılandırma Özellikleri>Genel Hedef Adı Python'dan superfastcode gibi deyimlerde from...import başvurmak için modülün adını belirtin. Python modülünü tanımlarken C++ kodunda aynı adı kullanırsınız. Modülün adı olarak projenin adını kullanmak için varsayılan $<ProjectName> değerini bırakın. için python_d.exeadın sonuna ekleyin _d .
      Yapılandırma Türü Dinamik Kitaplık (.dll)
      Yapılandırma Özellikleri>Gelişmiş Hedef Dosya Uzantısı .pyd (Python Uzantı Modülü)
      C/C++>Genel Ek Ekleme Dizinleri Python include klasörünü yüklemenize uygun şekilde ekleyin (örneğin, c:\Python36\include).
      C/C++>Önişlemci Önişlemci Tanımları Varsa, _DEBUG değerini CPython'un nondebug sürümüyle eşleşecek şekilde NDEBUG olarak değiştirin. python_d.exe kullandığınızda, bu değeri değiştirmeden bırakın.
      C/C++>Kod Oluşturma Çalışma Zamanı Kitaplığı CPython'un yayın (nondebug) sürümüyle eşleşecek çok iş parçacıklı DLL (/MD). python_d.exe kullandığınızda, bu değeri Çok İş Parçacıklı Hata Ayıklama DLL'si (/MDd) olarak bırakın.
      Temel Çalışma Zamanı Denetimleri Varsayılan
      Bağlayıcı>Genel Ek Kitaplık Dizinleri Yüklemeniz için uygun olan .lib dosyalarını içeren Python libs klasörünü ekleyin (örneğin, c:\Python36\libs). .py dosyaları içeren Lib klasörünü değil, .lib dosyalarını içeren libs klasörüne işaret etmeye dikkat edin.

      Önemli

      Proje özellikleri için bir seçenek olarak C/C++ sekmesi görüntülenmiyorsa, proje Visual Studio'nun C/C++ kaynak dosyaları olarak tanımlamış olduğu hiçbir kod dosyası içermez. .c veya .cpp dosya uzantısı olmayan bir kaynak dosya oluşturursanız bu koşul oluşabilir.

      C++ dosyasını oluştururken module.cpp yerine yanlışlıkla module.coo girdiyseniz, Visual Studio dosyayı oluşturur ancak dosya türünü C/C+ derleyicisi olarak ayarlamaz. Proje özellikleri iletişim kutusunda C/C++ özellikleri sekmesinin varlığını etkinleştirmek için bu dosya türü gereklidir. Kod dosyasını bir .cpp dosya uzantısıyla yeniden adlandırsanız bile yanlış kimlik doğrulaması kalır.

      Kod dosyası türünü düzgün ayarlamak için, Çözüm Gezgini kod dosyasına sağ tıklayın ve Özellikler'i seçin. Öğe Türü için C/C++ derleyicisi'ni seçin.

    4. Tüm özellikleri güncelleştirdikten sonra Tamam'ı seçin.

    Diğer derleme yapılandırması için adımları yineleyin.

  3. Geçerli yapılandırmanızı test edin. Her iki C++ projesinin hem hata ayıklama hem de yayın derlemeleri için aşağıdaki adımları yineleyin.

    1. Visual Studio araç çubuğunda Derleme yapılandırmasını Hata Ayıklama veya Yayın olarak ayarlayın:

      Screenshot that shows how to set the build configuration for the C++ project in Visual Studio.

    2. Çözüm Gezgini'da C++ projesine sağ tıklayın ve Oluştur'a tıklayın.

      .pyd dosyaları çözüm klasöründe, Hata Ayıklama ve Serbest Bırakma altındadır ve C++ proje klasörünün kendisinde değildir.

Kod ekleme ve yapılandırmayı test edin

Artık C++ dosyalarınıza kod eklemeye ve yayın derlemesini test etmeye hazırsınız.

  1. Superfastcode C++ projesi için kod düzenleyicisinde module.cpp dosyasını açın.

  2. module.cpp dosyasına aşağıdaki kodu yapıştırın:

    #include <Windows.h>
    #include <cmath>
    
    const double e = 2.7182818284590452353602874713527;
    
    double sinh_impl(double x) {
        return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
    }
    
    double cosh_impl(double x) {
        return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
    }
    
    double tanh_impl(double x) {
        return sinh_impl(x) / cosh_impl(x);
    }
    
  3. Değişikliklerinizi kaydedin.

  4. Kodunuzun doğru olduğunu onaylamak için C++ projesinin yayın yapılandırmasını oluşturun.

Superfastcode2 projesi için C++ dosyasına kod ekleme adımlarını tekrarlayın ve yayın derlemesini test edin.

C++ projelerini Python uzantılarına dönüştürme

C++ DLL'sini Python uzantısı yapmak için önce dışarı aktarılan yöntemleri Python türleriyle etkileşim kuracak şekilde değiştirirsiniz. Ardından modülü dışarı aktarmak için bir işlev ve modülün yöntemlerinin tanımlarını ekleyin.

Aşağıdaki bölümlerde, CPython uzantıları ve PyBind11 kullanılarak uzantıların nasıl oluşturulacağı gösterilmektedir. Superfasctcode projesi CPython uzantılarını kullanır ve superfasctcode2 projesi PyBind11'i uygular.

CPython uzantılarını kullanma

Bu bölümde sunulan kod hakkında daha fazla bilgi için bkz . Python/C API Başvuru Kılavuzu, özellikle modül nesneleri sayfası. Başvuru içeriğini gözden geçirirken sağ üstteki açılan listeden Python sürümünüzü seçtiğinizden emin olun.

  1. Superfastcode C++ projesi için kod düzenleyicisinde module.cpp dosyasını açın.

  2. Python.h üst bilgi dosyasını eklemek için module.cpp dosyasının en üstüne bir deyim ekleyin:

    #include <Python.h>
    
  3. tanh_impl Python türlerini kabul etmek ve döndürmek için yöntem kodunu değiştirin (başka bir ifadeyle):PyObject*

    PyObject* tanh_impl(PyObject* /* unused module reference */, PyObject* o) {
        double x = PyFloat_AsDouble(o);
        double tanh_x = sinh_impl(x) / cosh_impl(x);
        return PyFloat_FromDouble(tanh_x);
    }
    
  4. Dosyanın sonuna, C++ tanh_impl işlevinin Python'a nasıl sunılacağını tanımlamak için bir yapı ekleyin:

    static PyMethodDef superfastcode_methods[] = {
        // The first property is the name exposed to Python, fast_tanh
        // The second is the C++ function with the implementation
        // METH_O means it takes a single PyObject argument
        { "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr },
    
        // Terminate the array with an object containing nulls
        { nullptr, nullptr, 0, nullptr }
    };
    
  5. Özellikle deyimini kullanırken Python kodunuzda modüle nasıl başvurabileceğinizi from...import tanımlamak için başka bir yapı ekleyin.

    Bu kodda içeri aktarılan ad, Yapılandırma Özellikleri>Genel>Hedef Adı altındaki proje özelliklerindeki değerle eşleşmelidir.

    Aşağıdaki örnekte ad, "superfastcode" içinde superfastcode_methodstanımlandığından Python'da fast_tanh deyimini from superfastcode import fast_tanh kullanabileceğiniz anlamına gelir. C++ projesinin içindeki module.cpp gibi dosya adları önemsizdir.

    static PyModuleDef superfastcode_module = {
        PyModuleDef_HEAD_INIT,
        "superfastcode",                        // Module name to use with Python import statements
        "Provides some functions, but faster",  // Module description
        0,
        superfastcode_methods                   // Structure that defines the methods of the module
    };
    
  6. Python modülü yüklerken çağıran bir yöntem ekleyin. Yöntem adı olmalıdırPyInit_<module-name>; burada< modül adı> C++ projesinin Yapılandırma Özellikleri>Genel>Hedef Adı özelliğiyle tam olarak eşleşir. Başka bir ifadeyle, yöntem adı proje tarafından oluşturulan .pyd dosyasının dosya adıyla eşleşir.

    PyMODINIT_FUNC PyInit_superfastcode() {
        return PyModule_Create(&superfastcode_module);
    }
    
  7. C++ projesini oluşturun ve kodunuzu doğrulayın. Hatalarla karşılaşırsanız "Derleme hatalarını giderme" bölümüne bakın.

PyBind11 kullanma

Superfastcode projesinin önceki bölümünde yer alan adımları tamamlarsanız, alıştırmada C++ CPython uzantıları için modül yapılarını oluşturmak için ortak kod gerektiğini fark edebilirsiniz. Bu alıştırmada PyBind11'in kodlama işlemini basitleştirdiğini keşfedeceksiniz. Aynı sonucu elde etmek için ancak çok daha az kodla C++ üst bilgi dosyasında makrolar kullanırsınız. Ancak, Visual Studio'nın PyBind11 kitaplıklarını bulabilmesi ve dosyaları ekleyebilmesi için ek adımlar gerekir. Bu bölümdeki kod hakkında daha fazla bilgi için bkz . PyBind11 temel bilgileri.

PyBind11'i yükleme

İlk adım, proje yapılandırmanıza PyBind11 yüklemektir. Bu alıştırmada Geliştirici PowerShell penceresini kullanacaksınız.

  1. Araçlar>Komut Satırı>Geliştirici PowerShell penceresini açın.

  2. Geliştirici PowerShell penceresinde pip komutunu pip install pybind11 veya py -m pip install pybind11kullanarak PyBind11'i yükleyin.

    Visual Studio, PyBind11 ve bağımlı paketlerini yükler.

Projeye PyBind11 yolları ekleme

PyBind11 yüklendikten sonra, projenin Ek Ekleme Dizinleri özelliğine PyBind11 yollarını eklemeniz gerekir.

  1. Geliştirici PowerShell penceresinde veya py -m pybind11 --includeskomutunu python -m pybind11 --includes çalıştırın.

    Bu eylem, proje özelliklerinize eklemeniz gereken PyBind11 yollarının listesini yazdırır.

  2. Penceredeki yolların listesini vurgulayın ve pencere araç çubuğunda Kopyala (çift sayfa) öğesini seçin.

    Screenshot that shows how to highlight and copy the list of paths from the Developer PowerShell window in Visual Studio.

    Birleştirilmiş yolların listesi panonuza eklenir.

  3. Çözüm Gezgini superfastcode2 projesine sağ tıklayın ve Özellikler'i seçin.

  4. Özellik Sayfaları iletişim kutusunun üst kısmında, Yapılandırma alanı için Yayın'ı seçin. (Bu seçeneği Etkin ön ek.)

  5. İletişim kutusundaki C/C++>Genel sekmesinde, Ek Ekleme Dizinleri özelliğinin açılan menüsünü genişletin ve Düzenle'yi seçin.

  6. Açılan iletişim kutusunda, kopyalanan yolların listesini ekleyin:

    Geliştirici PowerShell penceresinden kopyalanan birleştirilmiş listedeki her yol için şu adımları yineleyin:

    1. Açılan iletişim kutusu araç çubuğunda Yeni Satır 'ı (artı simgesi olan klasör) seçin.

      Screenshot that shows how to add a PyBind11 path to the Additional Include Directories property.

      Visual Studio, yol listesinin en üstüne boş bir çizgi ekler ve ekleme imlecini en başa yerleştirir.

    2. PyBind11 yolunu boş satıra yapıştırın.

      Ayrıca Diğer seçenekler 'i (...) seçebilir ve yol konumuna göz atmak için açılan dosya gezgini iletişim kutusunu kullanabilirsiniz.

      Önemli

      • Yol ön ekini -I içeriyorsa, ön eki yoldan kaldırın.
      • Visual Studio'nın bir yolu tanıması için yolun ayrı bir satırda olması gerekir.

      Yeni bir yol ekledikten sonra Visual Studio, Değerlendirilen değer alanında onaylanan yolu gösterir.

  7. Açılan iletişim kutusundan çıkmak için Tamam'ı seçin.

  8. Özellik Sayfaları iletişim kutusunun üst kısmında, Ek Ekleme Dizinleri özelliğinin değerinin üzerine gelin ve PyBind11 yollarının mevcut olduğunu onaylayın.

  9. Özellik değişikliklerini uygulamak için Tamam'ı seçin.

module.cpp dosyasını güncelleştirme

Son adım, PyBind11 üst bilgi dosyasını ve makro kodunu proje C++ dosyasına eklemektir.

  1. superfastcode2 C++ projesi için kod düzenleyicisinde module.cpp dosyasını açın.

  2. pybind11.h üst bilgi dosyasını eklemek için module.cpp dosyasının en üstüne bir deyim ekleyin:

    #include <pybind11/pybind11.h>
    
  3. module.cpp dosyasının sonuna, C++ işlevine giriş noktasını tanımlamak için PYBIND11_MODULE makronun kodunu ekleyin:

    namespace py = pybind11;
    
    PYBIND11_MODULE(superfastcode2, m) {
        m.def("fast_tanh2", &tanh_impl, R"pbdoc(
            Compute a hyperbolic tangent of a single argument expressed in radians.
        )pbdoc");
    
    #ifdef VERSION_INFO
        m.attr("__version__") = VERSION_INFO;
    #else
        m.attr("__version__") = "dev";
    #endif
    }
    
  4. C++ projesini oluşturun ve kodunuzu doğrulayın. Hatalarla karşılaşırsanız derleme hatalarını giderme başlıklı sonraki bölüme bakın.

Derleme hatalarını giderme

C++ modülü derlemesinin başarısız olmasına neden olabilecek olası sorunlar için aşağıdaki bölümleri gözden geçirin.

Hata: Üst bilgi dosyası bulunamıyor

Visual Studio, E1696: "Python.h" veya C1083 dosyası açık kaynak: Ekleme dosyası açılamıyor: "Python.h": Böyle bir dosya veya dizin yok.

Bu hata, complier'ın projeniz için gerekli üst bilgi (.h) dosyasını bulamıyor olduğunu gösterir.

  • Süper hızlı kod projesi için C/C++>Genel>Ek Ekleme Dizinleri proje özelliğinin Python yüklemeniz için ekleme klasörünün yolunu içerdiğini doğrulayın. Proje özelliklerini yapılandırma'daki adımları gözden geçirin.

  • superfastcode2 projesi için, aynı proje özelliğinin PyBind11 yüklemeniz için include klasörünün yolunu içerdiğini doğrulayın. Ad PyBind paths to project adımlarını gözden geçirin.

Python yükleme yapılandırma bilgilerinize erişme hakkında daha fazla bilgi için Python belgelerine bakın.

Hata: Python kitaplıkları bulunamıyor

Visual Studio, bağlayıcının projeniz için gerekli kitaplık (DLL) dosyalarını bulamadığını belirten bir hata döndürür.

  • C++ projesi (superfastcode veya superfastcode2) için Bağlayıcı>Genel>Ek Kitaplık Dizinleri özelliğinin Python yüklemeniz için libs klasörünün yolunu içerdiğini doğrulayın. Proje özelliklerini yapılandırma'daki adımları gözden geçirin.

Python yükleme yapılandırma bilgilerinize erişme hakkında daha fazla bilgi için Python belgelerine bakın.

Visual Studio, x64 veya Win32 gibi projenizin hedef mimari yapılandırmasıyla ilgili bağlayıcı hataları bildirir.

  • C++ projesi (superfastcode veya superfastcode2) için hedef yapılandırmayı Python yüklemenizle eşleşecek şekilde değiştirin. Örneğin, C++ proje hedef yapılandırmanız Win32 ise ancak Python yüklemeniz 64 bit ise, C++ proje hedef yapılandırmasını x64 olarak değiştirin.

Kodu test edin ve sonuçları karşılaştırın

Artık DLL'leri Python uzantıları olarak yapılandırdığınıza göre, bunlara Python projesinden başvurabilir, modülleri içeri aktarabilir ve yöntemlerini kullanabilirsiniz.

DLL'nizi Python'da kullanılabilir hale getirme

DLL'nizi Python'ın kullanımına çeşitli yollarla sunabilirsiniz. Dikkate alınması gereken iki seçenek şunlardır:

Python projeniz ve C++ projeniz aynı çözümdeyse aşağıdaki yaklaşımı kullanabilirsiniz:

  1. Çözüm Gezgini'da Python projenizde Başvurular düğümüne sağ tıklayın ve Başvuru Ekle'yi seçin.

    Bu eylemi C++ projeniz için değil Python projeniz için gerçekleştirmeyi unutmayın.

  2. Başvuru Ekle iletişim kutusunda Projeler sekmesini genişletin.

  3. Hem superfastcode hem de superfastcode2 projelerinin onay kutularını seçin ve Tamam'ı seçin.

    Screenshot that shows how to add a reference to the super fast code project in Visual Studio.

Alternatif bir yaklaşım, Python ortamınıza C++ uzantı modülünü yüklemektir. Bu yöntem modülü diğer Python projelerinin kullanımına sunar. Daha fazla bilgi için kurulum araçları proje belgelerine bakın.

Python ortamınıza C++ uzantı modülünü yüklemek için aşağıdaki adımları tamamlayın:

  1. Çözüm Gezgini C++ projenize sağ tıklayın ve Yeni Öğe Ekle'yi>seçin.

  2. Dosya şablonları listesinde C++ Dosyası (.cpp) öğesini seçin.

  3. Dosyanın Adını setup.py olarak girin ve Ekle'yi seçin.

    Dosya adını Python (.py) uzantısıyla girdiğinizden emin olun. Visual Studio, C++ dosya şablonunun kullanılmasına rağmen dosyayı Python kodu olarak tanır.

    Visual Studio yeni dosyayı kod düzenleyicisinde açar.

  4. Aşağıdaki kodu yeni dosyaya yapıştırın. Uzantı yönteminize karşılık gelen kod sürümünü seçin:

    • CPython uzantıları (superfastcode projesi):

      from setuptools import setup, Extension
      
      sfc_module = Extension('superfastcode', sources = ['module.cpp'])
      
      setup(
          name='superfastcode',
          version='1.0',
          description='Python Package with superfastcode C++ extension',
          ext_modules=[sfc_module]
      )
      
    • PyBind11 (superfastcode2 projesi):

      from setuptools import setup, Extension
      import pybind11
      
      cpp_args = ['-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.7']
      
      sfc_module = Extension(
          'superfastcode2',
          sources=['module.cpp'],
          include_dirs=[pybind11.get_include()],
          language='c++',
          extra_compile_args=cpp_args,
      )
      
      setup(
          name='superfastcode2',
          version='1.0',
          description='Python package with superfastcode2 C++ extension (PyBind11)',
          ext_modules=[sfc_module],
      )
      
  5. C++ projesinde pyproject.toml adlı ikinci bir dosya oluşturun ve aşağıdaki kodu yapıştırın:

    [build-system]
    requires = ["setuptools", "wheel", "pybind11"]
    build-backend = "setuptools.build_meta"
    

    TOML (.toml) dosyası, yapılandırma dosyaları için Tom'un Bariz, En Düşük Dil biçimini kullanır.

  6. Uzantıyı oluşturmak için kod penceresi sekmesinde pyproject.toml dosya adına sağ tıklayın ve Tam Yolu Kopyala'yı seçin.

    Screenshot that shows how to copy the full path to the py project toml file in Visual Studio.

    Pyproject.toml adını kullanmadan önce yoldan silersiniz.

  7. Çözüm Gezgini'da çözüm için Python Ortamları düğümünü genişletin.

  8. Etkin Python ortamına sağ tıklayın (kalın yazıyla gösterilir) ve Python Paketlerini Yönet'i seçin.

    Python Ortamları bölmesi açılır.

    Gerekli paket zaten yüklüyse, bu bölmede listelendiğini görürsünüz.

    • Devam etmeden önce, paketi kaldırmak için paket adının yanındaki X işaretini seçin.

    Screenshot that shows how to uninstall a package in the Python Environments pane.

  9. Python Ortamları bölmesinin arama kutusuna kopyalanan yolu yapıştırın ve yolun sonundan pyproject.toml dosya adını silin.

    Screenshot that shows how to enter the path in the Python Environments pane to install the extension module.

  10. Kopyalanan yolun konumundan modülü yüklemek için Enter'ı seçin.

    İpucu

    Yükleme bir izin hatası nedeniyle başarısız olursa, bağımsız değişkeni komutun sonuna ekleyin --user ve yüklemeyi yeniden deneyin.

Python'dan DLL'yi çağırma

ÖNCEKI bölümde açıklandığı gibi DLL'yi Python için kullanılabilir hale getirdikten sonra, Python'dan ve superfastcode2.fast_tanh2 işlevlerini çağırmaya superfastcode.fast_tanh hazırsınız demektir. Ardından işlev performansını Python uygulamasıyla karşılaştırabilirsiniz.

Python'dan uzantı modülü DLL'sini çağırmak için şu adımları izleyin:

  1. Kod düzenleyicisinde Python projeniz için .py dosyasını açın.

  2. Dosyanın sonuna, DLL'lerden dışarı aktarılan yöntemleri çağırmak ve çıktılarını görüntülemek için aşağıdaki kodu ekleyin:

    from superfastcode import fast_tanh
    test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d] (CPython C++ extension)')
    
    from superfastcode2 import fast_tanh2
    test(lambda d: [fast_tanh2(x) for x in d], '[fast_tanh2(x) for x in d] (PyBind11 C++ extension)')
    
  3. Hata Ayıklama Olmadan Başlat'ı>seçerek Python programını çalıştırın veya Ctrl+F5 klavye kısayolunu kullanın.

    Not

    Hata Ayıklama olmadan başlat komutu kullanılamıyorsa, Çözüm Gezgini'de Python projesine sağ tıklayın ve Başlangıç Projesi Olarak Ayarla'yı seçin.

    Program yürütürken, C++ yordamlarının Python uygulamasından yaklaşık 5-20 kat daha hızlı çalıştığına dikkat edin.

    Aşağıda tipik bir program çıktısı örneği verilmişti:

    Running benchmarks with COUNT = 500000
    [tanh(x) for x in d] (Python implementation) took 0.758 seconds
    
    [fast_tanh(x) for x in d] (CPython C++ extension) took 0.076 seconds
    
    [fast_tanh2(x) for x in d] (PyBind11 C++ extension) took 0.204 seconds
    
  4. Zaman farklarının COUNT daha belirgin olması için değişkeni artırmayı deneyin.

    Hata ayıklama derlemesi daha az iyileştirilmiş olduğundan ve çeşitli hata denetimleri içerdiğinden, C++ modülünün hata ayıklama derlemesi de yayın derlemesinden daha yavaş çalışır. Karşılaştırma için derleme yapılandırmaları arasında geçiş yapmayı deneyin, ancak yayın yapılandırması için daha önce ayarladığınız özellikleri güncelleştirmeyi unutmayın.

İşlem hızını ve ek yükünü ele alma

Çıktıda PyBind11 uzantısının CPython uzantısı kadar hızlı olmadığını ancak saf Python uygulamasından daha hızlı olması gerektiğini fark edebilirsiniz. Farkın en önemli nedeni, METH_O bayrağının kullanılmasıdır. Bu bayrak birden çok parametreyi, parametre adını veya anahtar sözcük bağımsız değişkenlerini desteklemez. PyBind11, çağıranlara daha Python benzeri bir arabirim sağlamak için biraz daha karmaşık kodlar oluşturur. Test kodu işlevi 500.000 kez çağırdığından sonuçlar ek yükü büyük ölçüde büyütebilir.

Döngünün yerel Python koduna taşınarak for ek yükü daha da azaltabilirsiniz. Bu yaklaşım, her öğeyi işlemek için yineleyici protokol (veya işlev parametresi için PyBind11 py::iterable türü) kullanmayı içerir. Python ve C++ arasındaki yinelenen geçişleri kaldırmak, diziyi işlemek için gereken süreyi azaltmanın etkili bir yoludur.

İçeri aktarma hatalarını giderme

Modülünüzü içeri aktarmayı denediğinizde bir ImportError ileti alırsanız, bu iletiyi aşağıdaki yollardan biriyle çözebilirsiniz:

  • Bir proje başvurusu aracılığıyla derleme yaparken, C++ proje özelliklerinizin Python projeniz için etkinleştirilmiş Python ortamıyla eşleştiğinden emin olun. Ekle (.h) ve Kitaplık (DLL) dosyaları için aynı klasör konumlarının kullanıldığını onaylayın.

  • Çıkış dosyanızın superfastcode.pyd gibi doğru adlandırdığından emin olun. Yanlış bir ad veya uzantı, gerekli dosyanın içeri aktarılmasını engeller.

  • modülünüzü setup.py dosyasını kullanarak yüklerseniz Python projeniz için etkinleştirilmiş Python ortamında komutunu çalıştırdığınızdan pip emin olun. Çözüm Gezgini'da projeniz için etkin Python ortamını genişlettiğinizde, C++ projesi için superfastcode gibi bir giriş görmeniz gerekir.

C++ kodunda hata ayıklama

Visual Studio, Python ve C++ kodunda birlikte hata ayıklamayı destekler. Aşağıdaki adımlarda superfastcode C++ projesi için hata ayıklama işlemi gösterilmektedir, ancak işlem superfastcode2 projesi için aynıdır.

  1. Çözüm Gezgini'da Python projesine sağ tıklayın ve Özellikler'i seçin.

  2. Özellikler bölmesinde Hata Ayıkla sekmesini ve ardından Hata Ayıklama> Yerel kod hata ayıklamayı etkinleştir seçeneğini belirleyin.

    İpucu

    Yerel kod hata ayıklamayı etkinleştirdiğinizde, Program duraklatılmadan ve Devam etmek için herhangi bir tuşa basın istemi gösterilmeden Python çıkış penceresi kapatılabilir. Yerel kod hata ayıklamasını etkinleştirdikten sonra duraklatma ve istem zorlamak için, bağımsız değişkeni Hata Ayıkla sekmesindeki Yorumlayıcı Bağımsız Değişkenlerini Çalıştır>alanına ekleyin-i. Bu bağımsız değişken, kod çalıştırıldıktan sonra Python yorumlayıcısını etkileşimli moda geçirir. Program, pencereyi kapatmak için Ctrl+Z+Enter'ı seçmenizi bekler. Alternatif bir yaklaşım, Python programınızın sonuna ve os.system("pause") deyimleri eklemektirimport os. Bu kod özgün duraklatma istemini yineler.

  3. Özellik değişikliklerini kaydetmek için Dosya>Kaydet 'i (veya Ctrl+S) seçin.

  4. Visual Studio araç çubuğunda Derleme yapılandırmasını Hata Ayıklama olarak ayarlayın.

  5. Kodun hata ayıklayıcıda çalıştırılması genellikle daha uzun sürdüğünden, Python proje .py dosyanızdaki değişkeni varsayılan değerden yaklaşık beş kat daha küçük bir değerle değiştirmek COUNT isteyebilirsiniz. Örneğin, 500000olan değerini 100000 olarak değiştirin.

  6. C++ kodunuzda, yöntemin ilk satırında tanh_impl bir kesme noktası ayarlayın.

  7. Hata Ayıkla Hata Ayıklamayı>Başlat'ı seçerek hata ayıklayıcıyı başlatın veya F5 klavye kısayolunu kullanın.

    Kesme noktası kodu çağrıldığında hata ayıklayıcı durdurulur. Kesme noktasına isabet almazsa, yapılandırmanın Hata Ayıkla olarak ayarlandığından ve projeyi kaydettiğinizden emin olun; bu hata ayıklayıcıyı başlattığınızda otomatik olarak gerçekleşmez.

    Screenshot of C++ code that contains a breakpoint in Visual Studio.

  8. Kesme noktasında C++ kodunda adım adım ilerleyebilir, değişkenleri inceleyebilir ve benzeri işlemleri yapabilirsiniz. Bu özellikler hakkında daha fazla bilgi için bkz . Python ve C++ hatalarını birlikte ayıklama.

Alternatif yaklaşımlar

Python uzantılarını aşağıdaki tabloda açıklandığı gibi çeşitli yollarla oluşturabilirsiniz. İlk iki satır CPython ve PyBind11, bu makalede ele alınıyor.

Yaklaşım Eski Temsilci kullanıcılar
için C/C++ uzantı modülleri CPython 1991 Standart Kitaplık
PyBind11 (C++için önerilir) 2015
Cython (C için önerilir) 2007 gevent, kivy
HPy 2019
mypyc 2017
ctypes 2003 oscrypto
cffi 2013 şifreleme, pypy
Yu -dum 1996 crfsuite
Boost.Python 2002
cppyy 2017