转载 http://blog.konghy.cn/2018/04/29/setup-dot-py/

Python 有非常丰富的第三方库可以使用,很多开发者会向 pypi 上提交自己的 Python 包。要想向 pypi 包仓库提交自己开发的包,首先要将自己的代码打包,才能上传分发。

distutils 简介

distutils 是标准库中负责建立 Python 第三方库的安装器,使用它能够进行 Python 模块的安装和发布。distutils 对于简单的分发很有用,但功能缺少。大部分 Python 用户会使用更先进的 setuptools 模块.

setuptools 简介

阅读全文 »

基础

const、引用和函数默认参数的使用及注意事项

  1. const 的作用
    • 取代无参宏,增加类型检查功能。
    • 对指针类型做一些限定。

const 主要是语法层面的限定,实际上可以通过内存修改 const 变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>

#define PI 3.14f

int main(int argc, char** argv) {

printf("PI: %f\r\n", PI); // 3.140000
// const 取代无参宏,方便调试,增加类型检查。
const float CPI = 3.14f;
printf("CPI: %f\r\n", CPI); // 3.140000
*(float*)&CPI = 2.14f;
// 编译中直接替换为常量了,所以修改了CPI的值输出也是3.140000。
printf("CPI: %f\r\n", CPI); // 3.140000

// const 指针
// const 在 * 前面,则指针指向的内容无法修改。
const char* pbuffer = "hello";
pbuffer = NULL;
// pbuffer[0] = 'H'; 这条语句会出错,表达式必须是可修改的左值。

// const 在 * 后面,则指针变量的值无法修改。
char szBuffer[] = "world"; // 等价于 char * const szBuffer = "hello"
char* const cbuffer = szBuffer;
// cbuffer = NULL; 表达式必须是可修改的左值。
cbuffer[0] = 'W';

// const 在 * 前后都有,则指向的内容和指针的值都无法修改。
const char* const ccbuffer = szBuffer;
// ccbuffer = NULL; 表达式必须是可修改的左值。
// ccbuffer[0] = 'h';表达式必须是可修改的左值。
szBuffer[1] = 'O'; // 语法上不可修改,实际上可以通过内存修改
// printf("pbuffer: %s\r\n", pbuffer);
printf("cbuffer: %s\r\n", cbuffer);
printf("ccbuffer: %s\r\n", ccbuffer);
}
阅读全文 »

转载:https://abcdabcd987.com/ssh/

约定

本文不讲解 Linux 使用方法,只讲解机器之间的通信方法。
下文中行首的 local$ 以及 remote$ 等为命令行的提示符,不是输入的内容,用于区分当前是在哪台机子上。

基础

阅读全文 »

本文章记录使用 python 过程中易忘的知识,方便自己查阅。

设置 pypi 镜像

临时使用

1
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

注意,simple 不能少, 是 https 而不是 http

阅读全文 »

1. 安装gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
➜  ~ sudo apt install gradle

➜ ~ gradle -v
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass (file:/usr/share/java/groovy-all.jar) to method java.lang.Object.finalize()
WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.reflection.CachedClass
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

------------------------------------------------------------
Gradle 4.4.1
------------------------------------------------------------

Build time: 2012-12-21 00:00:00 UTC
Revision: none

Groovy: 2.4.16
Ant: Apache Ant(TM) version 1.10.5 compiled on March 28 2019
JVM: 11.0.4 (Ubuntu 11.0.4+11-post-Ubuntu-1ubuntu218.04.3)
OS: Linux 5.0.0-36-generic amd64

2. 入门前奏

2.1. 实现 hello world

阅读全文 »

本次阅读源码来自aosp Android 8.1.0_r1,在阅读过程中根据阅读的进度随手记录

有过 linux 编成经验的都应该知道使用 dlopen 需要包含 dlfcn.h 头文件,所以直接去aosp/bionic/libc/include/dlfcn.h 中找到 dlopen 的函数定义。

1
void* dlopen(const char* filename, int flag);

通过dlopen的定义找到其实现在 aosp/bionic/libdl/libdl.c 中,

1
2
3
4
5
6
7
8
9
// Proxy calls to bionic loader
void* dlopen(const char* filename, int flag) {
/*
__builtin_return_address(0)的含义是,得到当前函数返回地址,即此函数被别的函数调用,然后此函数执行完毕后,返回,所谓返回地址就是那时候的地址。
__builtin_return_address(1)的含义是,得到当前函数的调用者的返回地址。注意是调用者的返回地址,而不是函数起始地址。
*/
const void* caller_addr = __builtin_return_address(0);//可以理解为汇编 MOV R0, LR
return __loader_dlopen(filename, flag, caller_addr);
}
阅读全文 »
0%