1. 程式人生 > 其它 >Ctypes:python呼叫c的方法 (包括一個由gcc/python的32位/64位差異造成的OSerror的解決方案)

Ctypes:python呼叫c的方法 (包括一個由gcc/python的32位/64位差異造成的OSerror的解決方案)

Ctype為我們提供了一種在python中呼叫c的方法:

Step1:編寫C程式碼:(testoutput.c)

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

void print();

void print()
{printf("Hello World!\n");}

int main ( void )
{
    FILE *output;
    output = fopen("output.txt","w");
    
    if(output == NULL)
    {
         printf(
"Open filefailure!\n"); exit(1); } else { fprintf(output,"success\n"); } fclose(output); return 0; }

Step2:將C程式碼編譯為動態連結庫

gcc -m64 --share -o testoutput.dll -fPIC testoutput.c

注意這裡的字尾名:windows下為.dll,而linux下為.so

Step3:在python中應用

from ctypes import *

t 
= CDLL('./testoutput.dll') t.print() t.main()

問題:初始的Step2編譯沒有 -m64 選項,結果python在CDLL那行執行錯誤:

問題原因是gcc編譯器是32位的,但python是64位的(可以通過gcc -v 和 python -v 指令看出),而且此時32位gcc不支援 -m64 選項。

解決方案是裝64位的gcc,這樣達到了統一,問題解決。

P.S. 然而這樣的話就沒辦法 -m32 了。。一個麻煩的辦法是更改32位gcc和64位gcc在path路徑中的先後順序,這樣在前面的總是會被呼叫,實現了手動的切換。。

在生成32位和64位的.dll檔案後,如何在python中判斷需要呼叫哪個呢,這時候需要用到struct.calcsize("P")語句:

import struct
is_64 = (64 == struct.calcsize("P") * 8)

(這裡參考了https://www.likecs.com/show-204164801.html)

於是根據這個可以CDLL不同的dll檔案。

*以上程式碼在win10上執行