深入研究Python的源代码后,我发现它维护了一个PyInt_Objects 数组,范围从int(-5)到int(256)(@src/Objects/intobject.c)
一个小实验证明了这一点:
>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False
Run Code Online (Sandbox Code Playgroud)
但是如果我在py文件中一起运行这些代码(或者用分号连接它们),结果会有所不同:
>>> a = 257; b = 257; a is b
True
Run Code Online (Sandbox Code Playgroud)
我很好奇为什么它们仍然是同一个对象,所以我深入研究语法树和编译器,我想出了一个下面列出的调用层次结构:
PyRun_FileExFlags()
mod = PyParser_ASTFromFile()
node *n = PyParser_ParseFileFlagsEx() //source to cst
parsetoke()
ps = PyParser_New()
for (;;)
PyTokenizer_Get()
PyParser_AddToken(ps, ...)
mod = PyAST_FromNode(n, ...) //cst to ast
run_mod(mod, ...)
co = PyAST_Compile(mod, ...) //ast to CFG …Run Code Online (Sandbox Code Playgroud) 我知道有一个选项"-Os"来"优化尺寸",但它几乎没有影响,甚至在某些场合增加尺寸:(
strip(或"-s"选项)删除调试符号表,工作正常; 但它只能减少尺寸的小比例.
还有其他方法可以继续吗?
Shawn Chin在答案1中解决了问题.让我疯狂的是,编译mcrypt扩展,只有libmcrypt就足够了,没有必要编译mhash和mcrypt :(
我想为php编译mcrypt扩展(RHEL5.1,Intel i5 650),这是我的程序
# libmcrypt
tar zxf libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8
./configure --prefix=/home/felix021/lamp/libmcrypt/
make
make install
# mhash
tar jxf mhash-0.9.9.9.tar.bz2
cd mhash-0.9.9.9
./configure --prefix=/home/felix021/lamp/mhash/
make
make install
# mcrypt
LD_LIBRARY_PATH=/home/felix021/lamp/libmcrypt/lib:/home/felix021/lamp/mhash/lib
./configure --prefix=/home/felix021/lamp/mcrypt/ \
--with-libmcrypt-prefix=/home/felix021/lamp/libmcrypt
Run Code Online (Sandbox Code Playgroud)
配置失败并注意到:
checking for mhash_keygen in -lmhash... no
configure: error: "You need at least libmhash 0.8.15 to compile this program. \
http://mhash.sf.net/"
Run Code Online (Sandbox Code Playgroud)
所以我下载了mhash0.8.18和mhash0.8.15,但是发生了同样的错误.
我在0.8.15/8中查找了"mhash_keygen":
int mhash_keygen(xxx,xxx,xxx)
Run Code Online (Sandbox Code Playgroud)
它在0.9.9.9:
#if defined(PROTOTYPES)
mutils_error mhash_keygen(keygenid algorithm, ....)
#else
mutils_error mhash_keygen();
#endif
//typedef uint32 mutils_error
Run Code Online (Sandbox Code Playgroud)
但是,mcrypt-2.6.8/configure +12114,它是:
char …Run Code Online (Sandbox Code Playgroud) 原型gethostbyname_r是:
int gethostbyname_r(const char *name,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);
Run Code Online (Sandbox Code Playgroud)
为了避免不可重入gethostbyname,我写了这些东西:
int host2addr(const char *host, struct in_addr *addr) {
struct hostent he, *result;
int herr, ret, bufsz = 512;
char *buff = NULL;
do {
char *new_buff = (char *)realloc(buff, bufsz);
if (new_buff == NULL) {
free(buff);
return ENOMEM;
}
buff = new_buff;
ret = gethostbyname_r(host, &he, buff, bufsz, &result, &herr);
bufsz *= 2;
} while (ret == ERANGE); …Run Code Online (Sandbox Code Playgroud) dlsym可以从剥离的二进制文件中导入函数,这很奇怪.
谁能告诉我为什么/如何?
=== FILE: a.c ===
int a1() { return 1; }
int a2() { return 2; }
=== end of a.c ===
=== FILE: b.c ===
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
typedef int (*fint)();
fint dlsym_fint(void *handle, char *name)
{
fint x = (fint)dlsym(handle, name);
char *err = NULL;
if ((err = dlerror()) != NULL) {
printf("dlsym: %s\n", err);
exit(1);
}
return x;
}
int main()
{
void *dl = dlopen("a.so", RTLD_NOW);
fint a = NULL;
a = …Run Code Online (Sandbox Code Playgroud)