2009-09-07 19 views
16

Rozwijam się w systemie Windows, i szukałem wszędzie, nie znajdując nikogo, kto mówiłby o takich rzeczach.C++ z osadzaniem w Pythonie: awaria, jeśli Python nie jest zainstalowany

Stworzyłem aplikację C++ na moim komputerze stacjonarnym, w której osadzono Python 3.1 przy użyciu MSVC. Połączyłem python31.lib i uwzględniłem python31.dll w folderze uruchomionym aplikacji obok pliku wykonywalnego. Działa świetnie. Mój kod rozszerzenia i osadzania zdecydowanie działa i nie ma żadnych awarii.

Wysłałem folder run do mojego znajomego, który nie ma zainstalowanego Python, a aplikacja ulega awarii podczas fazy instalacji skryptów.

Kilka godzin temu wypróbowałem aplikację na moim laptopie z zainstalowanym Pythonem 2.6. Miałem takie samo zachowanie awaryjne jak mój przyjaciel, a poprzez debugowanie okazało się, że to nie było wywołanie Py_Initialize().

Zainstalowałem Python 3.1 na moim laptopie bez zmiany kodu aplikacji. Uruchomiłem to i działa idealnie. Odinstalowałem Python 3.1, a aplikacja ponownie się zawiesi. Wstawiłem kod w mojej aplikacji, aby dynamicznie łączyć się z lokalnym python31.dll, aby upewnić się, że go używa, ale nadal dostaję awarię.

Nie wiem, czy interpreter potrzebuje więcej niż DLL, aby uruchomić lub co. Nie byłem w stanie znaleźć żadnych zasobów na ten temat. Dokumentacja Pythona i inne przewodniki nie wydają się jak dotąd rozwiązywać kwestii rozpowszechniania aplikacji C/C++, które używają osadzania w Pythonie bez konieczności instalowania Pythona lokalnie. Wiem, że jest to bardziej problem w systemie Windows niż w systemie Unix, ale widziałem wiele aplikacji Windows C/C++, które lokalnie lokują Python i nie jestem pewien, jak to robią.

Czego jeszcze potrzebuję poza biblioteką DLL? Dlaczego działa po zainstalowaniu Pythona, a następnie przestaje działać po jego odinstalowaniu? Wygląda na to, że powinno być tak trywialnie; może dlatego nikt tak naprawdę nie mówi o tym. Niemniej jednak nie mogę wyjaśnić, jak sobie z tym problemem poradzić.

Dziękuję bardzo z góry.

+1

Czy wywołanie funkcji loadbiblioteka zakończyło się pomyślnie? Gdzie umieszczasz bibliotekę dll? Może to być tak proste, jak aplikacja nie może znaleźć biblioteki. – patros

+1

LoadLibrary powiodło się, podobnie jak GetProcAddress. Ponieważ mam ten sam wyjątek, co ja bez dynamicznego łącza (a nie z powodu naruszenia dostępu NULL), mam wrażenie, że Py_Initialize zostało wywołane. Biblioteka DLL znajduje się w katalogu uruchomień. Mój katalog uruchamiania zawiera:. \ Ss_server.exe,. \ Python31.dll,. \ Admin.sqlite,. \ Settings.py,. \ Err.txt – apostrophest

Odpowiedz

20

Oprócz pythonxy.dll, potrzebna jest również cała biblioteka Pythona, tj. Zawartość folderu lib oraz moduły rozszerzeń, tj. Zawartość folderu DLL. Bez standardowej biblioteki Python nawet się nie uruchomi, ponieważ próbuje znaleźć os.py (w 3.x; string.py w wersji 2.x). Podczas uruchamiania importuje wiele modułów, w szczególności site.py.

Istnieje wiele lokalizacji, w których szuka standardowej biblioteki; w twoich przypadkach ostatecznie znajduje to w rejestrze. Przedtem używa nazwy pliku wykonywalnego (ustawionej za pomocą Py_SetProgramName), próbując znaleźć punkt orientacyjny; sprawdza również plik python31.zip, który powinien być spakowaną kopią standardowej biblioteki. Sprawdza również, czy istnieje zmienna środowiskowa PYTHONHOME.

Możesz zabrać bibliotekę z rzeczy, których nie potrzebujesz; istnieją różne narzędzia, które obliczają zależności statycznie (w szczególności modułfinder).

Jeśli chcesz zminimalizować liczbę plików, można

  1. połączyć wszystkie moduły rozszerzeń statycznie do swojej pythonxy.dll lub nawet łącza pythonxy.dll statycznie do aplikacji
  2. użyć narzędzia zamarzaniem ; pozwoli to na połączenie kodu bajtowego standardowej biblioteki z twoim pythonxy.dll.
  3. (alternatywnie do 2.) użyj pythonxy.zip dla biblioteki standardowej.
+0

Dziękuję, Martin. Twoje wyjaśnienie wypełnia niektóre z luk, których nie mogłem wypełnić, szukając odpowiedzi. Zbadam niektóre z zaproponowanych przez ciebie rozwiązań. – apostrophest

+1

Zrobiłem python31.zip składający się z C: \ Python31 \ Lib \ *. * I C: \ Python31 \ DLLs \ *. * Umieściłem to obok mojej aplikacji EXE i python31.dll. Program działa! Zip ma 13 megabajtów, więc, jak sugerujesz, powinienem znaleźć to, czego potrzebuję i odłożyć go na później. Zaznaczam to jako rozwiązanie, dziękuję bardzo! – apostrophest

+0

Nie mogłem wykonać pracy python26.zip - wypróbowałem prawie wszystko. Czy jesteś pewien, że python był * nie * zainstalowany, gdy pracował plik python31.zip? Wszystkie pozostałe posty na stackoverflow (powodujące pracę w pythonxx.zip) również nie są odpowiedzi! – sambha

11

Nice. A jeśli nie chcesz zip, skopiować Python26 \ DLL & Python26 \ lib do katalogu exe jako:

.\myexe.exe  
.\python26.dll 
.\Python26\DLLs 
.\Python26\lib 

a następnie ustawić PYTHONHOME z Py_SetPythonHome() API. Najwyraźniej ten interfejs API nie znajduje się na liście "dozwolonych" połączeń przed Py_Initialize();

Poniżej pracował dla mnie na Windows (Python nie zainstalowany):

#include "stdafx.h" 
#include <iostream> 
#include "Python.h" 

using namespace std; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char pySearchPath[] = "Python26"; 
    Py_SetPythonHome(pySearchPath); 
    Py_Initialize(); 
    PyRun_SimpleString("from time import time,ctime\n" 
        "print 'Today is',ctime(time())\n"); 
    //cerr << Py_GetPath() << endl; 
    Py_Finalize(); 

    return 0; 
} 

Dobrze, że ścieżka wyszukiwania jest względna w.r.t exe. Py_GetPath może pokazać, gdzie wszystko szuka modułów.

+0

powyższe rozwiązanie działało dobrze dla administratora. dla użytkownika nie będącego administratorem aplikacja nie uruchamia się. jakieś pomysły ? –

+0

@balasbellobas Czy masz pywin32 w swoim python? Myślę, że miałem podobny problem (wbudowane wywołania programu Excel działały tylko jako "administrator"). Wystąpił pewien problem z gen_py, w którym Python próbował tworzyć pliki w niedozwolonym folderze (być może w plikach programu). Możesz chcieć więcej wyszukać w witrynie gen_py. Myślę, że po prostu musiałem usunąć niektóre pliki. Mam nadzieję, że to pomoże. – sambha

5

Zip standardowej biblioteki Pythona pracował dla mnie z Python27.

Spakowałem zawartość Lib i dll i upewniłem się, że nie ma dodatkowego podfolderu Python27 lub podfolderu Lib lub dll. to jest po prostu plik ZIP o nazwie python27.zip zawierający wszystkie pliki.

Skopiowałem ten plik ZIP i python27.dll wraz z plikiem wykonywalnym.

6

Chciałem dodać kilka dodatkowych informacji dla innych, którzy nadal mogą mieć problemy z tym, jak ja. Byłem w końcu stanie dostać mój wniosek jest wykonywana przy użyciu metody zaproponowane przez sambha użytkownika, to jest:

 
Program Files (x86)\ 
    MyApplicationFolder\ 
     MyApplication.exe 
     python27.dll 
     Python27\ 
      DLLs\ (contents of DLLs folder) 
      Lib\ (contents of Lib folder) 

... z jednej ważnej Ponadto: Musiałem także zainstalować Msvcr90.dll. Używam Pythona 2.7 i pozornie python27.dll wymaga MSVCR90.DLL (i być może innych MSVC * 90.DLL).

Rozwiązałem to, pobierając, instalując i uruchamiając pakiet "vcredist_x86.exe" z http://www.microsoft.com/en-us/download/details.aspx?id=29. Myślę, że chociaż nie jestem pewien, że musisz to zrobić w ten sposób przynajmniej na Win7, w przeciwieństwie do prostego umieszczania MSVC * 90.DLL obok twojego .exe, tak jak mogłeś to zrobić w przeszłości. Instalator Microsoft umieszcza pliki i rejestruje je w specjalny sposób pod Win7.

Próbowałem również metody pliku .zip, ale to nie zadziałało, nawet przy zainstalowanym MSVCR90.DLL.