最近在讀論文與到處Fork別人的專案的過程中,碰到了絕大部分使用Python,但為加速底層運算而使用C++來編寫函數的情況,在Windows 10 64位元的環境下讀取編譯好的so檔會出現「%1 不是正確的win32應用程式」,必須要自己在64位元的linux環境下重新編譯才能使用,在解決的過程中就順便記錄下來作為筆記。
假設今天我們分別使用C/C++寫了兩個簡單的函數求兩數總和:
//使用C編寫的test.c __declspec(dllexport) int sum(int a, int b) { return a + b; }
//使用C++編寫的test.cpp #define DLLEXPORT extern "C" __declspec(dllexport) DLLEXPORT int sum(int a, int b) { return a + b; }
若你使用的是Windows,必須加上 __declspec(dllexport) 來讓裡面的函數是可被使用的,但如果你用的是 linux 的環境,則可以將它忽略。你也可以加入header檔,這個步驟加或不加都是可以的。
//test.h int sum(int, int);
Windows 環境下,可以透過 Visual studio 建立 Dinamic-Link Library project,將程式碼納入後編譯即可。
Linux環境下,可用gcc或g++來進行編譯,在終端機輸入
gcc -Wall -Wextra -O -ansi -pedantic -shared test.c -o test.so
若遇到「LD Link Failed – Bad Value」,吐出像下面這樣的錯誤,通常也是因為64位元的作業系統造成的;
/usr/bin/ld: /tmp/ccxJbKUI.o: relocation R_X86_64_PC32 against symbol `entityTotal' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Bad value collect2: error: ld returned 1 exit status
可以輸入
g++ -std=c++11 -shared -fPIC -o test.so test.cpp
來解決這個問題。 得到了DLL/so檔之後,就可以在編寫Python的時候調用裡面的函數了,方法是這樣的:
from ctypes import cdll mydll = cdll.LoadLibrary('test.dll') mydll.sum(5, 3) > 8
時隔四年多 求版主能再更新一次
更新27了~麻煩><
是指下載的網頁嗎?
嗨嗨,你的名字也太可愛XD 可以試試看最…
已更新,感謝!