我有一个与SWIG很好地合作的小项目.特别是,我的一些函数返回std::vectors,它们被转换为Python中的元组.现在,我做了很多数字,所以我只是让它们从c ++代码返回后将这些转换为numpy数组.为此,我在SWIG中使用类似下面的内容.
%feature("pythonappend") My::Cool::Namespace::Data() const %{ if isinstance(val, tuple) : val = numpy.array(val) %}
Run Code Online (Sandbox Code Playgroud)
(实际上,有几个函数名为Data,其中一些返回浮点数,这就是为什么我检查它val实际上是一个元组.)这很有效.
但是,我也想使用-builtin现在可用的旗帜.调用这些数据函数很少见,而且大部分都是交互式的,所以它们的缓慢不是问题,但是还有其他慢速循环,内置选项显着加速.
问题是当我使用该标志时,会自动忽略pythonappend功能.现在,Data再次返回一个元组.有什么方法我仍然可以返回numpy数组?我尝试使用打字机,但它变成了一个巨大的混乱.
Borealid非常好地回答了这个问题.为了完整性,我包含了一些我需要的相关但略有不同的类型图,因为我通过const引用返回并使用向量向量(不要启动!).这些是不同的,我不希望任何其他人绊倒试图找出微小的差异.
%typemap(out) std::vector<int>& {
npy_intp result_size = $1->size();
npy_intp dims[1] = { result_size };
PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(1, dims, NPY_INT);
int* dat = (int*) PyArray_DATA(npy_arr);
for (size_t i = 0; i < result_size; ++i) { dat[i] = (*$1)[i]; }
$result = PyArray_Return(npy_arr);
}
%typemap(out) std::vector<std::vector<int> >& {
npy_intp result_size = $1->size();
npy_intp result_size2 = (result_size>0 ? …Run Code Online (Sandbox Code Playgroud) 我发现了我的python代码中的瓶颈,与psycho等一起玩.然后决定为性能编写ac/c ++扩展.
在swig的帮助下,你几乎不需要关心论点等.一切正常.
现在我的问题是:swig创建了一个非常大的py文件,它在调用实际的.pyd或.so代码之前执行了很多'checkings'和'PySwigObject'.
如果你手写这个文件或者让swig这样做,你们中是否有人有任何经验可以获得更多的性能.
在python中,在什么情况下SWIG比ctypes更适合在共享库中调用入口点?假设您还没有SWIG接口文件.
两者的性能指标是什么?
有没有经历过这个错误的人?
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.swig.simple-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "liborg.swig.simple.example.so"
Run Code Online (Sandbox Code Playgroud)
通过这种方式加载库时发生错误.
static {
System.loadLibrary("example");
}
Run Code Online (Sandbox Code Playgroud)
我确定'example'类存在于当前文件夹中.
我目前正在开发一个项目,我必须用Python包装C++类才能编写程序脚本.所以我的具体经验还涉及在我们的程序中嵌入Python解释器.
我尝试的替代方案是:
Boost.Python的
我喜欢Boost.Python生成的更干净的API,但事实上它需要用户安装额外的依赖项才能让我们切换到SWIG.
痛饮
SWIG对我们的主要优势是它不需要最终用户安装它来使用最终程序.
您曾经做过什么,以及您的经历是什么?
我有一个用C++编写的类接口.我有一些实现此接口的类也是用C++编写的.这些是在更大的C++程序的上下文中调用的,它基本上实现了"main".我希望能够在Python中编写这个接口的实现,并允许它们在更大的C++程序的上下文中使用,就好像它们只是用C++编写的一样.
有很多关于连接python和C++的文章,但我无法弄清楚如何做我想要的.我能找到的最近的是:http://www.cs.brown.edu/~jwicks/boost/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions,但这不是没错.
更具体地说,假设我有一个现有的C++接口定义如下:
// myif.h
class myif {
public:
virtual float myfunc(float a);
};
Run Code Online (Sandbox Code Playgroud)
我想要做的是:
// mycl.py
... some magic python stuff ...
class MyCl(myif):
def myfunc(a):
return a*2
Run Code Online (Sandbox Code Playgroud)
然后,回到我的C++代码中,我希望能够说出类似的话:
// mymain.cc
void main(...) {
... some magic c++ stuff ...
myif c = MyCl(); // get the python class
cout << c.myfunc(5) << endl; // should print 10
}
Run Code Online (Sandbox Code Playgroud)
我希望这很清楚;)
我正在构建一个用于Python的C++扩展.我看到这个警告是在编译过程中生成的 - 当一个类型:
python setup.py build_ext -i
Run Code Online (Sandbox Code Playgroud)
是什么造成的,我该如何解决?
顺便说一句,这是我的安装文件的副本:
#!/usr/bin/env python
"""
setup.py file for SWIG example
"""
from distutils.core import setup, Extension
example_module = Extension('_foolib',
sources=['example_wrap.cxx',
'../wrapper++/src/Foo.cpp'
],
libraries=["foopp"]
)
setup (name = 'foolib',
version = '0.1',
author = "Me, Myself and I",
description = """Example""",
ext_modules = [example_module],
py_modules = ["example"],
)
Run Code Online (Sandbox Code Playgroud)
我在Ubuntu上使用gcc 4.4.3
这与我在SWIG邮件列表上的问题重复.
我试图在我的SWIG绑定中使用stl容器.除了在Perl中进行stl映射处理外,一切都运行良好.在C++方面,我有
std::map<std::string, std::string> TryMap(const std::map<std::string, std::string> &map) {
std::map<std::string, std::string> modified(map);
modified["7"] = "!";
return modified;
}
Run Code Online (Sandbox Code Playgroud)
SWIG配置看起来像这样
%module stl
%include "std_string.i"
%include "std_map.i"
%template(StringStringMap) std::map<std::string, std::string>;
%{
#include "stl.h"
%}
%include "stl.h"
Run Code Online (Sandbox Code Playgroud)
在我的Python脚本中,我可以这样调用TryMap
print dict(stl.TryMap({'a': '4'}))
Run Code Online (Sandbox Code Playgroud)
并获得美丽的输出
{'a': '4', '7': '!'}
Run Code Online (Sandbox Code Playgroud)
但在Perl我打电话
print Dumper stl::TryMap({'a' => '4'});
Run Code Online (Sandbox Code Playgroud)
并得到一个错误
TypeError in method 'TryMap', argument 1 of type 'std::map< std::string,std::string > const &' at perl.pl line 7.
Run Code Online (Sandbox Code Playgroud)
我实际上可以做类似的事情
my $map = stl::TryMap(stl::StringStringMap->new());
print $map->get('7');
Run Code Online (Sandbox Code Playgroud)
并得到'!',但这不是一个选项,因为有很多遗留代码使用"TryMap",期望普通的Perl哈希作为其输出.
我相信有一种方法可以解决这个问题,因为如果我使用stl向量和字符串而不是map,SWIG可以很好地解决Python中的这个特殊问题,即使在Perl中也是如此.
有没有办法在SWIG中使用Perl处理stl映射?我正在使用最新的SWIG 2.0.7 …
似乎大多数与JNI(Java Native Interface)相关的文档或帮助程序库都涉及从Java调用本机代码.这似乎是它的主要用途,即使它能够更多.
我想主要在相反的方向上工作:通过向其添加一些Java库来修改现有的(相当大的)可移植C++程序.例如,我想让它通过JDBC调用数据库,或者通过JMS调用消息队列系统,或发送电子邮件,或调用我自己的Java类等.但是使用原始JNI这是非常不愉快和容易出错的.
所以我理想地想编写可以像C++/CLI一样调用CLR类的C++代码来调用Java类.就像是:
using namespace java::util::regex; // namespaces mapped
Pattern p = Pattern.compile("[,\\s]+");
array<java::lang::String> result =
p.split("one,two, three four , five");
for (int i=0; i < result.length(); i++)
std::cout << result[i] << std::endl;
Run Code Online (Sandbox Code Playgroud)
这样,我就不必通过传递名称和奇怪的签名字符串来手动完成获取方法ID的工作,并且可以防止由未经检查的API调用方法引起的编程错误.实际上它看起来很像等效的Java.
NB.我还在谈论使用JNI!作为一项基础技术,它非常适合我的需求.它"在进行中"并且高效.我不想在一个单独的进程中运行Java并对它进行RPC调用.JNI本身很好.我只想要一个愉快的界面.
必须有一个代码生成工具来创建等效的C++类,命名空间,方法等,以完全匹配我指定的一组Java类所公开的内容.生成的C++类将:
这样一个免费的,开源的,可移植的库/工具是存在还是我在做梦?
注意:我发现了这个现有的问题,但在那种情况下,OP并不像我一样对完美的要求......
更新:关于SWIG的评论引发了我之前的问题,这似乎表明它主要是相反的方向,所以不会做我想要的.
重要
更新:我已经开始研究自己的解决方案了:
https://github.com/danielearwicker/cppjvm
如果这已经存在,请告诉我!
NB.如果您正在考虑在自己的项目中使用它,请自由,但请记住,现在代码已经有几个小时了,到目前为止我只编写了三个非常不费力的测试.
我正在尝试将Python M2Crypto软件包安装到x86_64 RHEL 6.1计算机上的virtualenv中.此进程调用swig,失败并显示以下错误:
$ virtualenv -q --no-site-packages venv
$ pip install -E venv M2Crypto==0.20.2
Downloading/unpacking M2Crypto==0.20.2
Downloading M2Crypto-0.20.2.tar.gz (412Kb): 412Kb downloaded
Running setup.py egg_info for package M2Crypto
Installing collected packages: M2Crypto
Running setup.py install for M2Crypto
building 'M2Crypto.__m2crypto' extension
swigging SWIG/_m2crypto.i to SWIG/_m2crypto_wrap.c
swig -python -I/usr/include/python2.6 -I/usr/include -includeall -o SWIG/_m2crypto_wrap.c SWIG/_m2crypto.i
/usr/include/openssl/opensslconf.h:31: Error: CPP #error ""This openssl-devel package does not work your architecture?"". Use the -cpperraswarn option to continue swig processing.
error: command 'swig' failed with exit status 1 …Run Code Online (Sandbox Code Playgroud)