python与c++的混合调用

最近用c++写了一个基于Hidden Markov的输入法,说是输入法,其实只有两个功能,一个功能是读入语料库,另一个是输入拼音返回输出的汉字。写完了之后,我在想,既然python这么好用,我又不想重写一遍输入法的代码,那么能不能用python调用c++现成的东西呢,于是就有了接下来的内容。这篇博客的题目是混合调用,这里暂时只写了python调用c++的内容,c++调用python等遇到了这方面的问题我再补充,内容有不对的地方欢迎大家提出。

python调用c++

调用c++动态链接库

c++端

调用c++生成的动态链接库并不能直接使用c++的类,还是需要通过函数的方式将对类的调用转换为c风格的函数接口。如

#define DLL_API __declspec(dllexport)
extern "C" DLL_API int add(int a, int b);
int add(int a, int b)
{
    return a + b;
}

其中__declspec(dllexport)是声明该函数为导出函数,简单地说就是声明该函数可以被外部文件调用。具体生成dll的方法这里就不写了。对于生成的dll可以用Dependency Walker来查看,下面是我用Dependency Walker查看生成的dll的结果,可以看到我定义的add函数。
image

python端

python端的程序主要用到了ctypes模块,我这里用python3.5来举例子。

from ctypes import *
dll=WinDLL('vstest.dll')
res=dll.add(1,2)
print(res)
>>> 3

可以看到已经成功调用了add函数。

复杂数据类型的传递

结构体
c++
struct Structure
{
    int a;
    double b;
    char c;
};
extern "C" DLL_API Structure disp(int a, double b, char c);
Structure disp(int a, double b, char c)
{
    Structure res;
    res.a = a;
    res.b = b;
    res.c = c;
    return res;
}
python
class MyStruct(Structure):
  _fields_=[('a',c_int),
            ('b',c_double),
            ('c',c_char)
            ]
dll=WinDLL('vstest.dll')
dll.disp.restype=MyStruct
a=c_int(1)
b=c_double(2)
c=c_char(b'c')//涉及字符的操作,前面都加b表示字节操作
res=dll.disp(a,b,c)
print(res.a)
print(res.b)
print(res.c)
>>> 1
>>> 2.0
>>> b'c'
数组与指针
c++

下面这个函数的功能是将一个大小为10的字符数组反转,并且存到令一个字符数组内,传出字符数组指针。

extern "C" DLL_API char* reverse_chararray(char input[10]);
char * reverse_chararray(char input[10])
{
    char *p = new char[10];
    for (int i = 0; i < 9; i++)
        p[i] = input[8 - i];
    p[9] = '\0';
    return p;
}
python
dll=WinDLL('vstest.dll')
c_char10=c_char*10
inp=c_char10(b'A',b'l',b'o',b'h',b'a',b' ',b'C',b'p',b'p')
print(inp.value)
dll.reverse_chararray.restype=c_char_p
res=dll.reverse_chararray(inp)
print(res)
>>> b'Aloha Cpp'
>>> b'ppC aholA'

c++调用python

用到时再补

输入法预测结果

调用代码

from ctypes import *
class Res(Structure):
  _fields_=[('str',c_wchar_p),
            ('score',c_double)
            ]

dll=WinDLL('cnIME.dll')
dll.query.restype=POINTER(Res)
char_p_array=c_char_p*5
query=char_p_array()
query[0]=c_char_p(b'shu')
query[1]=c_char_p(b'ru')
query[2]=c_char_p(b'fa')
corpus=c_char_p(b'corpus.txt')
if dll.load_corpus(corpus):
  res=dll.query(query,3)
  print(res.contents.str)
  print(res.contents.score)

>>> 输入法
>>> -11.47650278637253

这里我输入“输入法”的拼音,预测的结果为输入法,后面的那个数字是得到的打分,实际是概率的对数。输入法如果有谁感兴趣可以去Github看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值