使用Jupyter测试并行运算与GPU运算,所以配置并使用了C++作为运行内核,这个帖子的主题就是cling内核的使用入门。主要包含:
1. 内核安装与配置;
2. Cling的交互式编程方式;
3. 交互式编程的动态库调用方式;
C++内核安装与配置
-
在JupyterLab中支持的C++内核与Jupyter Notebook一样的安装,就是安装Cling交互式C++编程工具。
-
Cling的安装方式有两种:
- 源代码安装
- 预编译二进制安装
源代码安装
- 请参考
12:cling的安装: https://www.jianshu.com/p/95c4616fedd7
二进制安装
- 下载二进制安装文件:
https://root.cern.ch/download/cling/

- 设置cling的路径
- 因为JupyterLab也是调用命令行实现交互式执行代码,所以需要能找到cling的命令行程序。在系统或者用户配置文件中设置:
export PATH="cling的路径": ${PATH}
- 用户配置文件一般都在用户HOME主目录下的:
.bash_profile
文件。 - 配置好以后,要么重启,要么使用 .(source命令)命令重新加载一下即可。
- 因为JupyterLab也是调用命令行实现交互式执行代码,所以需要能找到cling的命令行程序。在系统或者用户配置文件中设置:

- 安装cling到JupyterLab
- 这个安装很简单,JupyterLab本身提供工具安装内核;安转的官方参考地址:
https://github.com/root-project/cling/tree/master/tools/Jupyter
- 步骤1:切换到cling下载后的解压目录:
cd ${JupyterLab_HOME}/share/cling/Jupyter/kernel$
- 步骤2:使用pip的文件安装方式安装相关模块到Python:
pip install -e .
- 步骤3:配置cling的不同C++内核到JupyterLab环境:
jupyter-kernelspec install cling-cpp17
- 其中提供哪些版本,可以到cling的kernel目录下查看。(一般支持C11,C14,C17)
- 这个安装很简单,JupyterLab本身提供工具安装内核;安转的官方参考地址:

- 如果完成以上操作后,可以启动JupyterLab了
jupyter lab

交互式C++编程与非交互式编程
-
非交互式编程就是传统的编写源代码,然后预编译、编译、链接生成执行文件,最后执行。
- 非交互式C++的执行总是从main函数开始
-
交互式编程是目前高级语言差不多都支持的编程模式了,Javascript,Python,Go,Swift,R,Matlab都支持交互式编程。
- 交互式C++,有三个方面需要与非交互式编程区分开来。
- 代码不能与头文件引入混和在一起。
- main函数不在自动作为入口调用,而是及时直接执行。
- 不能重复定义:函数与变量。
- 交互式C++,有三个方面需要与非交互式编程区分开来。
JupyterLab运行C++语句例子
- 注意:
- 头文件与语句分开,可以尝试混合在一起执行看看错误效果。
- 没有main函数的概念了。
#include <iostream>
std::cout << "Hi,JupyterLab交互式C++编程!" << std::endl;
Hi,JupyterLab交互式C++编程!
(std::basic_ostream &) @0x7fff96461760
JupyterLab调用C++函数例子
- 注意:
- 函数不能重复定义;
- 函数定义
int add(int num_added, int num_add){
std::cout << "加法执行!" << std::endl;
return num_added + num_add;
}
- 函数调用
std::cout << add(45, 55) << std::endl;
加法执行!
100
(std::basic_ostream &) @0x7fff96461760
头文件与动态库
-
编程的两板斧:
- 语法
- 库调用
-
所以C++编程常见的就是各种库调用,一般标准库编译器自动加载,但是用户的so/dll lib库就需要用户自己处理:
- 传统的非交互式编程通过命令行的-I -L -l三个选项参数处理;
- 交互式编程就使用C++标准中的代码动态调用机制解决;
- 预处理扩展指令:
#progam
来处理,其中的cling的扩展就是:@pragma cling 扩展指令
- 预处理扩展指令:
动态库准备
- 代码-h文件
#ifndef FUNC_H
#define FUNC_H
int cv_add(int na, int nb);
#endif
- 代码-cpp
#include "func.h"
int cv_add(int na, int nb){
return na + nb;
}
- 动态库编译
- 其中的Makefile中的tab键,需要设置下,否则使用4个空白代替。
[Settings] -> [Text Editor Indentation] -> [Indent with Tab]
- 其中的Makefile中的tab键,需要设置下,否则使用4个空白代替。
- Makefile脚本
G++ =g++
SOURCES =func.cpp
LIBARGS =-fPIC --shared
LIBNAME =libfunc.so
main:$(SOURCES)
$(G++) $(LIBARGS) $(SOURCES) -o $(LIBNAME)
- 执行编译脚本
make main

调用动态库
- 头文件引入
- 这个需要单独引入的,如果有路径,请带上路径,我们例子中是src。
- 与可以使用pragma指定头文件路径。
- 头文件引入函数声明,解决C++强类型的语法要求,任何identifier都需要定义。
- 这个需要单独引入的,如果有路径,请带上路径,我们例子中是src。
#include "./src/func.h"
- 使用动态库
- 使用pragma预处理指令;
- 调用库函数;
#pragma cling add_library_path("./src")
#pragma cling load("func")
std::cout << cv_add(155, 245) << std::endl;
400
(std::basic_ostream &) @0x7fff96461760
- gragma预处理指令的三种使用方式
-
#pragma cling add_include_path("include_directory")
- 设置头文件目录
-
#pragma cling add_library_path("library_directory")
- 设置lib库文件目录
-
#pragma cling load("libname")
- 设置lib库名
-
- 注意:
- pragma在不同的编译器,这个扩展是不一样的。可以参考对应编译器的文档获取。
终端转义序列支持测试
- 实际上Mac与Unix/Linux支持转义序列的,在Jupyter中也支持的很好,下面是转义序列的例子(使用bash指令):

转义序列的例子
std::cout << "\033[31mHello\033[0m" << std::endl;
�[31mHello�[0m
(std::basic_ostream &) @0x7fff96461760
std::cout << "\033[34;41mWorld\033[0m" << std::endl;
�[34;41mWorld�[0m
(std::basic_ostream &) @0x7fff96461760
附录
- 转义序列可以参考我的一个帖子:
- 02.
ANSI/VT100
终端控制转义序列:https://www.jianshu.com/p/a7f22e71b5af
- 03.在linux终端中修改窗体标题:
https://www.jianshu.com/p/e1af426b1a04
- 02.
网友评论