【问题标题】:Problems with wrapping C++ class to python将 C++ 类包装到 python 的问题
【发布时间】:2016-10-19 12:42:38
【问题描述】:

对于我的项目(游戏的 ia),我需要一个 C 网络接口。我想用 Python 编写我的项目,所以我从 C TCP-Socket 函数创建了一个 C++ 包装器,以便在我的 Python 代码中将它与 c-types 一起使用:

#include <iostream>
#include <string>
#include "Socket.h"
#include "stdio.h"

void        Socket::s_connect(char *host, int port){
    const char *str;
    pe = getprotobyname("tcp");
    if (!pe){
        perror("Error get protocol");
        exit(1);
    }
    f = socket(AF_INET, SOCK_STREAM, pe->p_proto);
    if (f == -1){
        perror("Error create socker");
        exit(1);
    }
    s_in.sin_family      = AF_INET;
    s_in.sin_port        = htons(port);
    s_in.sin_addr.s_addr = inet_addr(host);
    if (connect(f, (const struct sockaddr *&)s_in, sizeof(s_in)) == -1){
        perror("Error on connect");
        close(f);
    }
}


void        Socket::s_send(char *msg){
    if (write(f, msg, strlen(msg)) == -1){
        printf("error write\n");
        perror("write");
        exit(1);
    }
}

char        *Socket::s_recv(){
    char    *buff;
    int     ret;

    buff = (char *)malloc(4096);
    ret = read(f, buff, 4096);
    if (ret < 0){
        if (close(f))
            exit(1);
    }
    return buff;
}
extern "C" {
    Socket  *Socket_new()
    {
        return (new Socket); 
    }

    void    Socket_connect(Socket *sock, char *host, int port)
    {
        sock->s_connect(host, port);
    }

    void    Socket_send(Socket *sock, char *msg)
    {
        sock->s_send(msg);
    }
}

Socket.h:

#ifndef SOCKET_HPP_
# define SOCKET_HPP_


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>

class Socket {
    int                 f, port;
    struct protoent     *pe;
    struct sockaddr_in  s_in;
    char                *ip;
public:
    void s_connect(char *host, int port);
    void s_send(char * msg);
    char *s_recv();
};

#endif

还有我的 Python 类:

#!/usr/bin/python

import sys
from ctypes import cdll

lib = cdll.LoadLibrary('./libsocket.so')

class Socket(object):
    def __init__(self):
        self.obj = lib.Socket_new()


    def s_connect(self, host, port):
        print(host, port)
        lib.Socket_connect(self.obj, host, int(port))


    def s_send(self, msg):
        lib.Socket_send(self.obj, msg)

    def s_recv(self):
        lib.Socket_recv(self.obj)

    def main(arg):
        sock = Socket()
        sock.s_connect(arg[1], arg[2])
        sock.s_send("coucou")

    if __name__ == "__main__":
        main(sys.argv)

我的 extern C func 无法读取从 Python 发送的字符串我可以发送端口号,但我的 C++ 函数无法读取主机的字符串值。 如果我将 char * 更改为 std::string 我会遇到同样的问题。 我是不是做错了什么?

谢谢

【问题讨论】:

  • 使用 python socket 模块要容易得多。
  • 是的,我知道,但是我的项目需要一个 C 网络接口,这是我的项目指令之一。
  • 嗯,你用的是Python2还是Python3?这对字符的大小很重要......
  • 当你说“无法读取主机的字符串值”时,究竟发生了什么?
  • 等一下,你在哪里将 python 映射到你的 C++ 类? libsocket.so 是标准 C 网络库的一部分。您是否将 C++ DLL 与 C 库同名?

标签: python c++ c sockets ctypes


【解决方案1】:

正如您所说您使用的是 Python 3 版本,ctypes 模块的文档指出 Python unicode 字符串 (str) 对应于 C 中的宽字符数组 (wchar_t *),并且 Python 字节字符串 ( bytes) 对应窄字符数组 (char *)。

因此,根据您是否要实际处理 unicode 字符,您应该:

  • 要么使用bytes Python 端(琐碎):

    sock.s_connect(arg[1].encode('latin1'), arg[2])
    
  • 或使用wchar_t C 端(可能更难...)

【讨论】:

    猜你喜欢
    • 2020-11-14
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多