在python里调用c语言代码


Linux

c语言代码

#include<stdio.h>
int  add(){
    int sum = 0;
    int i;
    for(i = 1;i<=100000;i++){
    sum+=i;
    }
    printf("%d",sum);
    return sum;
}

需要用gcc 编译

此c语言的文件名为cName

编程成的so文件的名字为xName

gcc -shared -Wl,-soname,xName -o Xname.so -fPIC cName

编译命令我写了个python脚本

import os
file_name = input("输入你要转换的c语言的文件名:")
file_name2 = input("编译成的so文件的名字:")
shell = f"gcc -shared -Wl,-soname,{file_name2} -o {file_name2}.dll -fPIC {file_name}"
print(shell)
os.system(shell)

编译成.so文件后

写python代码

import ctypes

result = ctypes.cdll.LoadLibrary('./add.so')

result.add()
/*
705082704
705082704
*/

Win

编译命令的.so改为.dll

gcc -shared -Wl,-soname,xName -o Xname.dll -fPIC cName

会报错

原因: 此.dll文件也需要.dll依赖,,所以

Win 安装cygwin ,这是一个软件,

输入命令查看差哪些依赖

ldd add.dll
/*
ldd add.dll
        ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x7ffe68360000)
        KERNEL32.DLL => /cygdrive/c/Windows/System32/KERNEL32.DLL (0x7ffe66d20000)
        KERNELBASE.dll => /cygdrive/c/Windows/System32/KERNELBASE.dll (0x7ffe652f0000)
        apphelp.dll => /cygdrive/c/Windows/SYSTEM32/apphelp.dll (0x7ffe62fe0000)
        add.dll => /cygdrive/e/python/cTopython/add.dll (0x71140000)
*/

PS: 我现在没成功

放大招Cython

pip install Cpython  //Anaconda自带

首先Win要安装vs2019,安装下面两个

Imgur

准备工作就完成了

首先新建一个fib.pyx文件,这个格式是c语言和python公共的格式

cpdef c和python公用函数

cdef c语言用函数

def python语言函数

cpdef int fib(int n):
    if n==1:
        return 1
    if n==0:
        return 0
    return fib(n-1)+fib(n-2)

新建setup.py文件

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

filename = 'fib'  # 源文件名 编译后的名字
full_filename = 'fib.pyx'  # 包含后缀的源文件名   编译前名字

setup(
    cmdclass={'build_ext': build_ext},
    ext_modules=[Extension(filename, [full_filename])]  # 配置需要cython编译的源文件
)
#  python setup.py build_ext --inplace

分割线

还可以用第二种方法,推荐第二种

直接纯用c语言写代码

#include<stdio.h>
int fib(int n){
    if(n==0){
        return 1;
    }
    if(n==1){
        return 1;
    }
    return fib(n-1)+fib(n-2);
}
保存为.h文件

再写一个.pyx文件

cdef extern from "fib.h":
    cdef int fib(int n)

def fib_py(int n):
    return fib(n)

分割线结束


然后在命令行里面

 python setup.py build_ext --inplace

会生成build文件夹和fib.cp37-win_amd64.pyd文件,

Imgur

我们只需要导入fib包就可以使用了

import fib
import time

t1 = time.time()
fib.fib(40)
t2 = time.time()
print(t2-t1)

def fib(n):
    if n==1:
        return 1
    if n==0:
        return 0
    return fib(n-1)+fib(n-2)

t1 = time.time()
fib(40)
t2 = time.time()
print(t2-t1)

/*
0.726057767868042
51.39848494529724
*/
# 你可以看看差距有点大,太大了

至此,,骚操作都完成了

PS : linux下用这个一定要装python-dev和gcc,当然python必须的

# Centos
yum install python3-devel
# Ubuntu
apt-get install python3-dev

文章作者: anlen123
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 anlen123 !
 上一篇
Pycharm连接到远程服务器 Pycharm连接到远程服务器
连接到SSH 输入对的Ip端口,账号密码就可以连接了, 需要改一下ssh中文,编码 这样就可以正常显示中文了 远程连接文件夹项目在本地我新建了一个名字叫做linux的文件夹,来储存服务器上的 然后点击如图所示 这里选择SFTP 这里的
2020-05-22 anlen123
下一篇 
1371.每个元音包含偶数次的最长子字符串 1371.每个元音包含偶数次的最长子字符串
1371. 每个元音包含偶数次的最长子字符串给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 'a','e','i','o','u' ,在子字符串中都恰好出现了偶数次。 示例 1: 输入:s = "ele
2020-05-20 anlen123
  目录