Парадоксон: тихий сбой Python-файла ctypes.CDLL при импорте, но не при прямом запуске - как это возможно? - PullRequest
3 голосов
/ 02 июля 2019

Итак, будучи парнем из Linux, я натолкнулся на нечто довольно загадочное в Windows, которое просто не могу объяснить.

У меня есть структура проекта, аналогичная этому примеру:

D:\PROJECT
|
|   tolkien.py
|   __init__.py
|   
\---MiddleEarth
    |   gondor.py
    |   isengrad.c
    |   __init__.py
    |   
    \---lib
            isengrad.so

Проблема: Я скомпилирую isengrad.c в общий библиотека isengrad.so, затем загружаю его в gondor.py. Моя цель - импортировать gondor.py в tolkien.py.
* * * * * * * * * * * * * * * * * * *

. * * * * * * * * * * * * * *. Если я импортирую его, код существует в тот момент, когда я загружаю общую библиотеку через ctypes.CDLL, без ошибок.

Размножение: Содержимое файлов (добавлено несколько «сообщений о состоянии», чтобы отслеживать, где происходит проблема):

isengrad.c:

int isengrad(int hobbit){
    return hobbit/2;
}

Затем он компилируется в isengrad.so с

D:\project>chdir MiddleEarth
D:\project\MiddleEarth>gcc -fPIC -shared -o lib/isengrad.so isengrad.c

Доступ к общей библиотеке осуществляется в gondor.py :

print("started gondor")

import os, ctypes
path_to_isengrad = "D:/project/MiddleEarth/lib/isengrad.so"  

print("gondor loads isengrad")
gondor = ctypes.CDLL(path_to_isengrad)     # <--- crashes here when imported, not when ran directly
print("gondor loaded isengrad")


gondor.isengrad.argtypes = (ctypes.c_int,)

def faramir(hobbit):
    catched_hobbits = gondor.isengrad(hobbit)
    return catched_hobbits

if __name__ == '__main__':
    print(faramir(5))
    print("gondor ran")

print("gondor finished")

, который затем импортируется в tolkien.py :

print("started tolkien")
from MiddleEarth import gondor
print("tolkien imported gondor")

got = gondor.faramir(4)
print(got)

print("tolkien worked")

Теперь проверьте, что происходит, когда я использую gondor.py напрямую VS, когда я импортирую его в tolkien.py:

D:\project>python MiddleEarth/gondor.py
started gondor
gondor loads isengrad
gondor loaded isengrad
2
gondor ran
gondor finished

D:\project>python tolkien.py
started tolkien
started gondor
gondor loads isengrad

D:\project>

Непосредственный запуск не вызывает никаких проблем. Но его импорт приводит к сбою всего этого без каких-либо слов и обратной трассировки при загрузке общей библиотеки. Как это вообще происходит? Я даже жестко прописал путь к разделяемой библиотеке, поэтому проблема с другим рабочим каталогом не должна быть проблемой ... У меня не было проблем с тем же проектом на Kubuntu, так что это, вероятно, некоторые вещи, связанные с Windows.

Окружающая среда:

  • Python: Python 3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
  • ОС: Windows 10 10.0.17134 Build 17134 (установлена ​​на C:)
  • GCC: устанавливается через Cygwin, версия 7.4.0
  • Пожалуйста, спросите, нужны ли какие-либо другие данные.
...