zoukankan      html  css  js  c++  java
  • C/C++与Python实现混编(详细注释)

    github博客传送门
    csdn博客传送门

    网上找了好多教程都是转载的同一个人的,并且没有讲清楚 嵌入的关键步骤,整理后今天先来点简单的.

    主讲 c/c++ 编译为 .so 文件 嵌入 Python 实现混编

    目录:

    1. C语言版 hello
    2. C++语言版 hello
    3. C语言版加法器 有参无返回值
    4. C语言版加法器 有参有返回值
    5. C++语言版加法器 有参无返回值
    6. C++语言版加法器 有参有返回值
    7. C++语言Class版

    环境

    1. Python执行环境 (随便安装个Python版本添加 path就可以使用)
    2. c/c++ 执行环境 (我安装的是Dev-C++开发者工具 因为它小, 然后将 dev安装目录下的bin文件夹的路径添加到path环境变量即可在命令提示符使用)

    如果有尝试失败的可以下载我编译好的 .so 文件尝试使用

    下载链接:https://download.csdn.net/download/zhanghao3389/10723128
    文件目录
    所有文件夹

    命令解释:
    gcc c语言编译命令
    g++ c++语言编译命令
    参数 -o hello.so 输出 hello.so文件
    参数 -shared 共享的
    参数 -fPIC 告诉编绎器使用GOT和PLT的方法重定位
    最后 跟上自己写的 文件名
    例: gcc -o hello_c.so -shared -fPIC hello_c.c // 将 hello_c.c 编译生成了 hello_c.so 文件在当前目录下



    每个代码第一行注释是当前文件名

    C语言版 hello

    // hello_c.c
    #include<stdio.h>
    #include<stdlib.h>
    void hello()                       // 定义一个 hello的方法
    {
        printf("hello python and c");  // 输出一段字符串
    }
    

    打开命令提示符进入当前文件夹输入命令
    gcc -o hello_c.so -shared -fPIC hello_c.c
    当前文件夹下生成一个 hello_c.so 文件
    编写Python版调用程序
    并执行Python程序

    # hello_c.py
    import ctypes                 # 导入ctypes包
    so = ctypes.cdll.LoadLibrary  # 将包中的LoadLibrary方法赋给 so
    func = so("./hello_c.so")     # 用 LoadLibrary 方法 打开当前文件夹下的 打包为 .so 格式的文件 并赋给func
    func.hello()                  # 调用 func中的hello方法
    


    C++语言版 hello

    // hello_c++.cpp
    #include<iostream>
    using namespace std;  // 命名空间
    
               // 比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。
               // 这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。
    extern "C" // extern修饰符可用于指示C或者C++函数的调用规范。
    {
        void hello()                                  // 定义一个hello方法
        {
            cout << "hello python I'm cout" << endl;  // 输出一段字符串
            printf("hello python I'm printf");        // 输出一段字符串
        }
    }
    

    打开命令提示符进入当前文件夹输入命令
    g++ -o hello_c++.so -shared -fPIC hello_c++.cpp
    当前文件夹下生成一个 hello_c++.so 文件
    编写Python版调用程序
    并执行Python程序

    # hello_c++.py
    import ctypes                 # 导入ctypes包
    so = ctypes.cdll.LoadLibrary  # 将包中的LoadLibrary方法赋给 so
    func = so("./hello_c++.so")   # 用 LoadLibrary 方法 打开当前文件夹下的 打包为 .so 格式的文件 并赋给func
    func.hello()                  # 调用 func中的hello方法
    


    C语言版加法器 有参无返回值

    // add_c_1.c
    #include <stdio.h>  
    #include <stdlib.h>  
    int add(int a, int b)  // 定义一个 add方法 返回值为 int 传入两个参数 a,b 类型为 int
    {
        int result;                             // 定义一个 int 类型的 result变量
        printf("you input %d and %d
    ", a, b);  // 输出传入的两个参数
        result = a + b;                         // 计算两个参数相加的结果赋给 result
        printf("result is: %d", result);        // 输出计算结果后的值
    }
    

    打开命令提示符进入当前文件夹输入命令
    gcc -o add_c_1.so -shared -fPIC add_c_1.c
    当前文件夹下生成一个 add_c_1.so 文件
    编写Python版调用程序
    并执行Python程序

    # add_c_1.py
    import ctypes                 # 导入ctypes包
    so = ctypes.cdll.LoadLibrary  # 将包中的LoadLibrary方法赋给 so
    func = so("./add_c_1.so")     # 用 LoadLibrary 方法 打开当前文件夹下的 打包为 .so 格式的文件 并赋给func
    func.add(6, 8)                # 调用 func中的add方法 并传值 6, 8 给它
    


    C语言版加法器 有参有返回值

    // add_c_2.c
    #include <stdio.h>  
    #include <stdlib.h>  
    int add(int a, int b)                       // 定义一个 add方法 返回值为 int 传入两个参数 a,b 类型为 int
    {
        printf("you input %d and %d
    ", a, b);  // 输出传入的两个参数
        return a+b;                             // 返回计算后的值
    }
    

    打开命令提示符进入当前文件夹输入命令
    gcc -o add_c_2.so -shared -fPIC add_c_2.c
    当前文件夹下生成一个 add_c_2.so 文件
    编写Python版调用程序
    并执行Python程序

    # add_c_2.py
    import ctypes                 # 导入ctypes包
    so = ctypes.cdll.LoadLibrary  # 将包中的LoadLibrary方法赋给 so
    func = so("./add_c_2.so")     # 用 LoadLibrary 方法 打开当前文件夹下的 打包为 .so 格式的文件 并赋给func
    print(func.add(6, 8))         # 调用 func中的add方法 并传值 6, 8 给它
    


    C++语言版加法器 有参无返回值

    // add_c++_1.cpp
    #include<iostream>
    using namespace std;  // 命名空间
               // 比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。
               // 这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。
    extern "C" // extern修饰符可用于指示C或者C++函数的调用规范。
    {
        int add(int a, int b)  // 定义一个 add方法 返回值为 int 传入两个参数 a,b 类型为 int
        {
            int result;                                                // 定义一个 int 类型的 result变量
            cout << "you input " << a << " and " << b << ", I'm cout." << endl;  // 输出传入的两个参数
            printf("you input %d and %d, I'm printf.
    ", a, b);        // 输出传入的两个参数
            result = a + b;                                            // 计算两个参数相加的结果赋给 result
            cout << "result is: " << result << ", I'm cout." << endl;  // 输出计算结果后的值
            printf("result is: %d, I'm printf.
    ", result);            // 输出计算结果后的值
        }
    }
    

    g++ -o add_c++_1.so -shared -fPIC add_c++_1.cpp
    当前文件夹下生成一个 add_c++_1.so 文件

    # add_c++_1.py
    import ctypes                 # 导入ctypes包
    so = ctypes.cdll.LoadLibrary  # 将包中的LoadLibrary方法赋给 so
    func = so("add_c++_1.so")     # 用 LoadLibrary 方法 打开当前文件夹下的 打包为 .so 格式的文件 并赋给func
    func.add(66, 88)              # 调用 func中的add方法 并传值 66, 88 给它
    


    C++语言版加法器 有参有返回值

    // add_c++_2.cpp
    #include<iostream>
    using namespace std;  // 命名空间
               // 比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。
               // 这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。
    extern "C" // extern修饰符可用于指示C或者C++函数的调用规范。
    {
        int add(int a, int b)  // 定义一个 add方法 返回值为 int 传入两个参数 a,b 类型为 int
        {
            cout << "you input " << a << " and " << b << ", I'm cout." << endl;  // 输出传入的两个参数
            printf("you input %d and %d, I'm printf.
    ", a, b);                  // 输出传入的两个参数
            return a+b;                                                          // 返回a+b后的值
        }
    }
    

    g++ -o add_c++_2.so -shared -fPIC add_c++_2.cpp
    当前文件夹下生成一个 add_c++_2.so 文件

    # add_c++_2.py
    import ctypes                 # 导入ctypes包
    so = ctypes.cdll.LoadLibrary  # 将包中的LoadLibrary方法赋给 so
    func = so("add_c++_2.so")     # 用 LoadLibrary 方法 打开当前文件夹下的 打包为 .so 格式的文件 并赋给func
    print(func.add(66, 88))       # 调用 func中的add方法 并传值 66, 88 给它
    


    C++语言Class版

    // c++class.cpp
    #include <iostream>  
    using namespace std;                            // 命名空间
      
    class HelloAndAdd                               // 定义一个 hello的方法 和一个 add的方法
    {
        public:  
            void hello();                           // 定义一个hello的方法 无参无返回值
            void add(int a, int b);                 // 定义一个 add 方法 传入两个值 进行加法运算
    };  
    void HelloAndAdd::hello()                       // 定义HelloAndAdd里 hello方法的主体
    {
        cout<<"Hello C++ class , I'm cout."<<endl;  // 输出
        printf("Hello C++ class , I'm printf.");    // 输出
    }
      
    void HelloAndAdd::add(int a, int b)                            // 定义HelloAndAdd里 add 方法的主体
    {
        int result;                                                // 定义一个result 接收传入两个参数的结果
        cout << "you input " << a << " and " << b << ", I'm cout." << endl;  // 输出传入的两个参数
        printf("you input %d and %d, I'm printf.
    ", a, b);        // 输出传入的两个参数
        result = a+b;                                              // 计算两个参数相加的结果赋给 result
        cout << "result is: " << result << ", I'm cout." << endl;  // 输出计算结果后的值
        printf("result is: %d, I'm printf.
    ", result);            // 输出计算结果后的值
        
    }
    
               // 比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。
               // 这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。
    extern "C" // extern修饰符可用于指示C或者C++函数的调用规范。
    {
        HelloAndAdd haa;           // 实例化HelloAndAdd对象为 haa
        void hello()               // 定义Python访问该方法的 方法名
        {
            haa.hello();           // 传入上述方法执行的主体 等价于 return haa.hello();
        }
        void add(int a, int b)     // 定义Python访问该方法的 方法名 并传入参数
        {
            return haa.add(a, b);  // 传入上述方法执行的主体 并传入参数
        }
    }
    

    g++ -o c++class.so -shared -fPIC c++class.cpp
    当前文件夹下生成一个 c++class.so 文件

    # c++class.py
    import ctypes                 # 导入ctypes包
    so = ctypes.cdll.LoadLibrary  # 将包中的LoadLibrary方法赋给 so
    func = so("./c++class.so")    # 用 LoadLibrary 方法 打开当前文件夹下的 打包为 .so 格式的文件 并赋给func
    func.hello()                  # 调用 func中的hello方法
    print('
    ----------')
    func.add(10, 20)              # 调用 func中的add方法 并传入参数 10, 20
    

    编写不易,求助攻一个...

    print_r('点个赞吧');
    var_dump('点个赞吧');
    NSLog(@"点个赞吧!")
    System.out.println("点个赞吧!");
    console.log("点个赞吧!");
    print("点个赞吧!");
    printf("点个赞吧!
    ");
    cout << "点个赞吧!" << endl;
    Console.WriteLine("点个赞吧!");
    fmt.Println("点个赞吧!")
    Response.Write("点个赞吧");
    alert(’点个赞吧’)
    
  • 相关阅读:
    POJ 1509 Glass Beads【字符串最小表示法】
    Codeforces 665C Simple Strings【暴力,贪心】
    Codeforces 665D Simple Subset【构造】
    HDU 5667 Sequence【矩阵快速幂+费马小定理】
    Codeforces 667D World Tour【最短路+枚举】
    Codeforces 667D World Tour【最短路+枚举】
    HDU 5676 ztr loves lucky numbers【DFS】
    Codeforces 667C Reberland Linguistics【DFS】
    前端学习笔记三
    Datawhale编程——动态规划DP
  • 原文地址:https://www.cnblogs.com/Mrzhang3389/p/9796623.html
Copyright © 2011-2022 走看看