其他语言调用 C++ 简述

91 阅读2分钟

在现代软件开发中,单一语言往往无法满足所有需求。C++作为高性能的系统级编程语言,经常需要与其他语言进行交互。本文介绍 Python 与 javascript 调用 C++ 的方法。

Python 调用 C++

使用 pybind11

pybind11 是目前最流行的C++/Python绑定库,它提供了简洁的API。

步骤1: 安装必要的依赖

# 安装setuptools(用于构建扩展)
pip install setuptools

# 安装pybind11
pip install pybind11

步骤2: 创建C++源文件

// example.cpp
#include <pybind11/pybind11.h>

namespace py = pybind11;

int add(int a, int b) {
    return a + b;
}

std::string greet(const std::string& name) {
    return "Hello, " + name + "!";
}

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin";
    m.def("add", &add, "Add two numbers");
    m.def("greet", &greet, "Greet someone");
}

步骤3: 创建setup.py文件

# setup.py
from setuptools import setup, Extension
import pybind11

ext_modules = [
    Extension(
        "example",
        ["example.cpp"],
        include_dirs=[pybind11.get_include()],
        language='c++'
    ),
]

setup(
    name="example",
    ext_modules=ext_modules,
    install_requires=['pybind11>=2.4.3'],
    setup_requires=['pybind11>=2.4.3'],
)

步骤4: 编译和安装

# 在包含example.cpp和setup.py的目录中运行
python setup.py build_ext --inplace

步骤5: Python中使用

# test_example.py
import example

# 调用函数
result = example.add(3, 4)
print(f"3 + 4 = {result}")  # 输出: 3 + 4 = 7

# 调用字符串函数
message = example.greet("World")
print(message)  # 输出: Hello, World!

运行测试:

python test_example.py

使用 ctypes (更简单的方法)

对于简单的C函数,可以使用Python的ctypes模块:

步骤1: 创建C++代码并编译为共享库

// math_lib.cpp
extern "C" {
    int add(int a, int b) {
        return a + b;
    }
    
    double multiply(double a, double b) {
        return a * b;
    }
}

步骤2: 编译为共享库

# Linux/Mac
g++ -shared -fPIC math_lib.cpp -o math_lib.so

# Windows
g++ -shared math_lib.cpp -o math_lib.dll

步骤3: Python调用

# test_ctypes.py
import ctypes

# 加载共享库
lib = ctypes.CDLL('./math_lib.so')  # Linux/Mac
# lib = ctypes.CDLL('./math_lib.dll')  # Windows

# 调用函数
result = lib.add(3, 4)
print(f"3 + 4 = {result}")  # 输出: 3 + 4 = 7

# 调用浮点数函数
lib.multiply.argtypes = [ctypes.c_double, ctypes.c_double]
lib.multiply.restype = ctypes.c_double
result = lib.multiply(2.5, 3.0)
print(f"2.5 * 3.0 = {result}")  # 输出: 2.5 * 3.0 = 7.5

运行测试:

python test_ctypes.py

Node.js 调用 C++

使用 N-API (Node-API)

步骤1: 创建项目目录

mkdir node-cpp-demo && cd node-cpp-demo
npm init -y

步骤2: 安装node-gyp

npm install -g node-gyp

步骤3: 创建C++源文件

// math_addon.cpp
#include <node_api.h>

napi_value Add(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    double num1, num2;
    napi_get_value_double(env, args[0], &num1);
    napi_get_value_double(env, args[1], &num2);
    
    napi_value sum;
    napi_create_double(env, num1 + num2, &sum);
    
    return sum;
}

napi_value Init(napi_env env, napi_value exports) {
    napi_value fn;
    napi_create_function(env, nullptr, 0, Add, nullptr, &fn);
    napi_set_named_property(env, exports, "add", fn);
    return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

步骤4: 创建binding.gyp配置文件

{
  "targets": [
    {
      "target_name": "math_addon",
      "sources": [ "math_addon.cpp" ]
    }
  ]
}

步骤5: 编译插件

node-gyp configure
node-gyp build

步骤6: 创建JavaScript测试文件

// test.js
const mathAddon = require('./build/Release/math_addon');

const result = mathAddon.add(3, 4);
console.log(`3 + 4 = ${result}`); // 输出: 3 + 4 = 7

步骤7: 运行测试

node test.js

在浏览器中调用 C++

步骤1: 安装Emscripten

# 克隆Emscripten仓库
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk

# 安装最新版本
./emsdk install latest
./emsdk activate latest

# 设置环境变量
source ./emsdk_env.sh

步骤2: 创建C++代码

// math.cpp
#include <emscripten/bind.h>

using namespace emscripten;

int add(int a, int b) {
    return a + b;
}

double multiply(double a, double b) {
    return a * b;
}

EMSCRIPTEN_BINDINGS(module) {
    function("add", &add);
    function("multiply", &multiply);
}

步骤3: 编译为WebAssembly

emcc math.cpp -o math.js -s WASM=1 -s EXPORTED_FUNCTIONS='["_add", "_multiply"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'

步骤4: 创建HTML页面

<!DOCTYPE html>
<html>
<head>
    <title>C++ WebAssembly 示例</title>
</head>
<body>
    <h1>C++ WebAssembly 计算器</h1>
    <input type="number" id="num1" placeholder="数字1" value="3">
    <input type="number" id="num2" placeholder="数字2" value="4">
    <button onclick="calculate()">计算</button>
    <div id="result"></div>

    <script src="math.js"></script>
    <script>
        Module.onRuntimeInitialized = function() {
            console.log("WebAssembly 模块已加载");
            calculate(); // 自动计算一次
        };

        function calculate() {
            const num1 = parseInt(document.getElementById('num1').value);
            const num2 = parseInt(document.getElementById('num2').value);
            
            // 调用C++函数
            const sum = Module.ccall('add', 'number', ['number', 'number'], [num1, num2]);
            
            document.getElementById('result').innerHTML = 
                `${num1} + ${num2} = ${sum}`;
        }
    </script>
</body>
</html>

步骤5: 运行本地服务器

# 使用Python启动本地服务器
python3 -m http.server 8000

# 或者使用Node.js
npx http-server

步骤6: 在浏览器中访问 打开浏览器访问 http://localhost:8000,你会看到计算器界面。