Python ctypes给出分段错误

时间:2014-09-16 06:47:15

标签: python c++ ctypes

我试图将ctypes用于着名的re2库。但我得到了分段错误。

这是代码

tryone.cpp

#include <re2/re2.h>
#include <iostream>
#include <tuple>

using namespace re2;

RE2 re("([^ @]+)@([^ @]+)");

std::pair<string, string> match(string rawtext){
    string uname;
    string domain;
    RE2::PartialMatch(rawtext, re, &uname, &domain);
    return std::make_pair(uname, domain);
}

bool isit(string rawtext){
    return RE2::PartialMatch(rawtext, re);
}

extern "C" {
    bool there(string rawtext){ return isit(rawtext); }
}

int  main() {
    if(isit("zbcd@xyz.com")){
    printf("PASS\n");
    }
}

然后我用g ++编译

g++ -I/usr/local/include -L/usr/local/lib -c -fPIC -std=c++11 tryone.cpp -lre2 -pthread -o tryone.o
g++ -shared -Wl,-soname,libmatch.so -L/usr/local/lib -lre2 -o libmatch.so  tryone.o /usr/local/lib/libre2.so.0

这是我的python包装函数

from ctypes import cdll, c_char_p, c_bool
lib = cdll.LoadLibrary('./libmatch.so')

lib.there.argtypes = [c_char_p]
lib.there.restype = c_bool

print lib.there("abcd@xyz.com")

但是当我运行python代码时,它给我分段错误python wrapper.py

1 个答案:

答案 0 :(得分:0)

第一步,根据名称和部分来判断你的这个&#34; re2&#34;库(这是如此着名我不知道它;虽然它在Debian中,似乎没有任何需要它)是一个正则表达式库。你已经在Python的re模块中拥有了一个非常灵活的模块。

其次,ctypes是本机库的不安全接口;你需要完全正确地完成所有事情,这意味着要理解底层类型系统,包括可以分配或释放内存的时间以及通过哪些例程。它的正常用例是包装具有C接口的库而不编写任何非Python代码。在这种情况下,内存分配应该很容易,因为你只是返回一个bool并且不保留字符串引用。

但最重要的是,C ++ std::string根本就不是你所描述的char*(事实上,C没有字符串数据类型!)。在C ++中,用于允许函数重载的基于类型的名称修改会使这一点变得明显,因为你没有找到bool there(char*)函数,但是使用extern "C"你使用C&C的链接来获取确切地说;并且ctypes从包装器中获取所有类型信息。你可以通过从char指针构造一个字符串来修复你的there()包装器(虽然你也应该传递长度,因为Python字符串可能包含nul),但是这个练习似乎是一种让事情变得更难的迂回方式。

考虑到你的方法需要C和Python包装器,没有编译器来键入检查组合,使用swig之类的东西可能会更好。