考虑一个简单的函数
def increment(self):
self.count += 1
Run Code Online (Sandbox Code Playgroud)
它通过Cython运行并编译成扩展模块.假设现在我想把这个函数作为一个类的方法.例如:
class Counter:
def __init__(self):
self.count = 0
from compiled_extension import increment
Counter.increment = increment
Run Code Online (Sandbox Code Playgroud)
现在这不起作用,因为C级别的调用约定将被打破.例如:
>>> c = Counter()
>>> c.increment()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: increment() takes exactly one argument (0 given)
Run Code Online (Sandbox Code Playgroud)
但是在Python 2中,我们可以通过执行以下操作将函数转换为未绑定的方法:
Counter.increment = types.MethodType(increment, None, Counter)
Run Code Online (Sandbox Code Playgroud)
我怎样才能在Python 3中完成同样的事情?
一种简单的方法是使用纤薄的包装:
from functools import wraps
def method_wraper(f):
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wraps(f)(wrapper)
Counter.increment = method_wrapper(increment)
Run Code Online (Sandbox Code Playgroud)
有更有效的方法吗?
是否有希望dlopen(NULL, ...)为静态编译的二进制文件运行和获取符号?
例如,使用以下代码,如果程序是动态编译的,我可以使用符号-rdynamic.
$ gcc -o foo foo.c -ldl -rdynamic
$ ./foo bar
In bar!
Run Code Online (Sandbox Code Playgroud)
但随着-static我得到一个神秘的错误信息:
$ gcc -static -o foo foo.c -ldl -rdynamic
/tmp/cc5LSrI5.o: In function `main':
foo.c:(.text+0x3a): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ./foo bar
/lib/x86_64-linux-gnu/: cannot read file data: Is a directory
Run Code Online (Sandbox Code Playgroud)
以下来源foo.c:
#include <dlfcn.h>
#include <stdio.h>
int foo() { printf("In foo!\n"); }
int …Run Code Online (Sandbox Code Playgroud)