Я использую swig для соединения функции C ++ с моими библиотеками Python. Мне удалось все скомпилировать и создать файл .so. После компиляции с помощью swig и создания необходимой библиотеки я попробовал функцию connect_PE_func на ipython, здесь я вставляю выполненные мной команды python:
В [1]: импорт connect_PE_func
В [2]:test = connect_PE_func.connect_pe_func (["192.168.2.170", "2600000026"])
завершить вызов после выброса экземпляра 'std :: logic_error' what (): basic_string :: _ M_construct null not valid Aborted
Понятия не имею, что происходит. Функция C ++ создает сокет TCP и отправляет шестнадцатеричный код на устройство, которое отвечает другим шестнадцатеричным кодом, с терминала с кодом C ++, который я пишу:
connect_PE_func 192.168.1.170 260000026
и работает отлично.
Я прикрепляю код к файлам .c .he .i, которые я использовал с swig для получения .so.
спасибо.
connect_PE.func.cpp
#include <stdio.h>
#include <errno.h>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <unistd.h>
#include <sstream>
#include "connect_PE_func.h"
using namespace std;
char * connect_pe_func(int argc, char *argv[])
{
int sockfd, n;
int connected = 0;
struct sockaddr_in servaddr;
std::string serveraddr = argv[1];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(serveraddr.c_str());
servaddr.sin_port = htons(9761);
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
std::string pref_hex;
std::string hex("0x");
std::string test = argv[2];
size_t numbytes = test.size() / 2;
uint8_t command[numbytes];
for (size_t w = 0, x = 0; w < numbytes; ++w, x += 2)
{
pref_hex = hex + test.substr(x, 2);
cout << pref_hex;
command[w] = stoi(pref_hex, nullptr, 16);
}
int bytes_to_send = sizeof(command);
send(sockfd, command, bytes_to_send, 0);
uint8_t output_command[numbytes];
recv(sockfd, output_command, bytes_to_send, 0);
char test_out[10];
for (size_t w = 0, x = 0; w < numbytes; ++w, x += 2)
{
test_out[x] = (char)output_command[w];
}
return test_out;
}
connect_PE_func.h:
// file: connect_PE_func.h
char* connect_pe_func(char *argv[], int argc);
**connect_PE_func.i:**
/* file: connect_PE_func.i */
%module connect_PE_func
%include <argcargv.i>
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv)}
%{
/* Everything in this block will be copied in the wrapper file. We include the C header file necessary to compile the int$
*/
#include "connect_PE_func.h"
// extern char *connect_pe_func(int argc, char *argv[]);
%}
%typemap(in) (int argc, char *argv[]) {
int i;
if (!PyList_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a list");
return NULL;
}
$1 = PyList_Size($input);
$2 = (char **) malloc(($1+1)*sizeof(char *));
for (i = 0; i < $1; i++) {
PyObject *s = PyList_GetItem($input,i);
if (!PyUnicode_AsUTF8(s)) {
free($2);
PyErr_SetString(PyExc_ValueError, "List items must be strings");
return NULL;
}
$2[i] = PyString_AsString(s);
}
$2[i] = 0;
}
%typemap(freearg) (int argc, char *argv[]) {
free($2); // If here is uneeded, free(NULL) is legal
}
/* list functions to be interfaced: */
char* connect_pe_func(int argc, char *argv[]);