簡體   English   中英

Cython DLL 擴展編譯使用 WINAPI 在鏈接期間失敗並出現錯誤 LNK2001

[英]Cython DLL extension compilation using WINAPI fails during linking with error LNK2001

我正在嘗試為(Photron)相機驅動程序 DLL 編寫 Cython 接口。 這個庫提供了一個 SDK 和 header 文件和 Windows 庫,用於 32 位和 64 位。 我已經在 VisualStudio 中使用這個庫成功編譯了 C++ 示例。 另一方面,Cython 編譯在鏈接時失敗。

The custom Cython code consists of a typedefs.pxd file containing the types, a photron.pxd file containing the constants and function declarations from the SDK header and a wrapper cdef class in a camera.pyx file.

在 setup.py 文件的 Extension(從 setuptools 導入)部分中,我包含了以下部分:

include_dirs=[s.path.abspath(os.path.normpath('./include'))],
libraries=[os.path.join(os.path.abspath(os.curdir), 'Lib', '64bit(x64)', 'PDCLIB')],
library_dirs=[os.path.abspath(os.path.normpath('./Lib/64bit(x64)'))],

我還嘗試了 C++ 編譯成功的命令行中的標志。 為了讓初始 cythonization 步驟起作用(生成 cpp 文件),我還必須將其添加到 SDK 的 header 中:

    #include <windows.h>

以下是 pxd 文件的相關摘錄:

from typedefs cimport ulong, uint

cdef extern from "PDCFUNC.h":
    ulong PDC_CloseDevice(ulong nDeviceNo, ulong *pErrorCode)

當我嘗試編譯代碼時,我得到了 cpp 文件,但是當我嘗試鏈接時,對於我在 pxd 文件中聲明的每個函數,我得到一系列如下所示的行:

camera.obj : error LNK2001: unresolved external symbol "unsigned long __cdecl PDC_CloseDevice(unsigned long,unsigned long *)" (?PDC_CloseDevice@@YAKKPEAK@Z)

我想這是因為 linker 試圖在指定的標頭中找到一個 __cdecl function 盡管函數在 header 文件中以這種方式聲明:

unsigned long WINAPI PDC_CloseDevice(unsigned long nDeviceNo, unsigned long *pErrorCode);

由於 Cython 文檔明確指出支持調用約定,因此我嘗試:

  1. 將 WINAPI 調用約定添加到 pxd 文件,但在文件的 cythonization 過程中,C 變量聲明中出現語法錯誤
  2. 直接添加__stdcall調用約定,因為程序無論如何都應該以 64 位編譯。 但是我仍然得到 LNK2001 行來尋找__cdecl ,就好像 Cython 繞過了調用約定一樣。 實際上,這是生成的 cpp 文件中的行:
    __pyx_v_ret = PDC_CloseDevice(__pyx_v_self->device_nb, (&__pyx_v_error_code));

__cdecl警告也可能是一條紅鯡魚,但我沒有其他線索,而且我通常不會在 Windows 下編譯,所以我對這些工具的了解有限。

在嘗試了其他所有內容(包括正確編譯的 Visual Studio 項目中的所有選項)之后,我用一個最小的示例重新啟動,在pxd文件中只有以下內容

cdef extern from "PDCLIB.h"
    ulong __stdcall PDC_Init(ulong *pErrorCode)
    ulong __stdcall PDC_CloseDevice(ulong nDeviceNo, ulong *pErrorCode)

和一個更簡單的pyx文件,除了擴展名之外,它具有相同的名稱。

from pyphotron_pdclib cimport *

from typedefs cimport ulong, uint

cpdef init_pdc_lib():
    cdef ulong error_code = 0
    success = PDC_Init(&error_code)
    assert success != 0
    
cpdef close_cam(ulong dev_num):
    cdef ulong error_code = 0
    success = PDC_CloseDevice(dev_num, &error_code)
    assert success != 0

我在編譯中看到的主要區別是

  1. 它現在在 c 中編譯,因為沒有更多的擴展類型(cdef 類)
  2. pyx文件與pxd文件同名

安裝文件中的編譯和鏈接選項如下:

extra_compile_args=['/Gz', '/fp:precise', '/Zc:wchar_t', '/Zc:forScope', '/Zc:inline'],
extra_link_args=['/DEBUG', '/MACHINE:X64'],

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM