将字符串数组从python传递到C并在for循环中使用(包含代码)
我试图将两个字符串数组从python传入C,在嵌套的for循环中使用它们,将它们与一个参数进行比较,如果两个字符串满足此参数,我将它们附加到C中的一个新字符串数组中。函数结束时,我返回新的比较字符串数组。这个函数是在python中使用CDLL调用的,这个新的字符串数组是在我的python脚本中使用的将字符串数组从python传递到C并在for循环中使用(包含代码),python,c,ctypes,Python,C,Ctypes,我试图将两个字符串数组从python传入C,在嵌套的for循环中使用它们,将它们与一个参数进行比较,如果两个字符串满足此参数,我将它们附加到C中的一个新字符串数组中。函数结束时,我返回新的比较字符串数组。这个函数是在python中使用CDLL调用的,这个新的字符串数组是在我的python脚本中使用的 #In Python: PyOne = ["Apple", "Orange", "Banana"] PyTwo = ["Cuc
#In Python:
PyOne = ["Apple", "Orange", "Banana"]
PyTwo = ["Cucumber", "Mango", "Pineapple", "Apple"]
我已将这些代码翻译成以下代码,以便在我的C函数中使用:
#In Python:
PyOne = ["Apple", "Orange", "Banana"]
PyOne_bytes = []
for i in range(len(PyOne)):
PyOne_bytes.append(bytes(PyOne[i], 'utf-8'))
One_array = (ctypes.c_char_p * (len(PyOne_bytes)+1))()
One_array[:-1] = PyOne_bytes
PyTwo = ["Cucumber", "Mango", "Pineapple", "Apple"]
PyTwo_bytes = []
for i in range(len(PyTwo)):
PyTwo_bytes(bytes(PyTwo[i], 'utf-8'))
Two_array = (ctypes.c_char_p * (len(PyTwo_bytes)+1))()
Two_array[:-1] = PyTwo_bytes
c.mainForLoop.argtypes = [POINTER(c_char_p), POINTER(c_char_p)]
c.mainForLoop.restype = ctypes.c_char_p
print(c.mainForLoop(One_array, Two_array))
上面的代码将现有的Python字符串数组转换为可由C解释的数组
这是我的C函数:
// In C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SCALING_FACTOR 0.1
#include <ctype.h>
...
char ** mainForLoop(const char ** PyOne, const char ** PyTwo) {
char ** matches = malloc(100 * sizeof(char*));
size_t i = 0;
size_t j = 0;
for (i = 0; i < sizeof(PyOne)/sizeof(PyOne[0]); i++) {
for (j = 0; j < sizeof(PyTwo)/sizeof(PyTwo[0]); j++) {
double v = comparison(PyOne[i], PyTwo[i]);
if (v > 4) {
strcat(matches, (PyOne[i]));
strcat(matches, (";"));
}
}
}
return matches;
}
例如,如果比较(“苹果”、“黄瓜”)=5(即>4),比较(“橙色”、“芒果”)=7(即>4),以及所有其他比较()<4,那么我会预期,由于以下原因
// In C
double v = comparison(PyOne[i], PyTwo[i]);
if (v > 4) {
strcat(matches, (PyOne[i]));
strcat(matches, (";"));
}
为了
但目前,这张照片显示:
>>> b'Apple;'
我不知道我的代码哪里做错了。我对C有点陌生,我已经尝试了我能想到的一切,任何帮助都将不胜感激,解释也将是ace
谢谢大家!
编辑:
以下是我的新代码:
// In C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void free_list(char** list, size_t size) {
for(size_t i = 0; i < size; ++i) if (list[i]) free(list[i]);
free(list);
}
char ** mainForLoop(const char ** PyOne, const char ** PyTwo, size_t sizeOne, size_t sizeTwo) {
size_t i = 0;
size_t j = 0;
char ** matches = malloc(sizeOne * sizeof(char *));
char temp[100] = {0};
for (i = 0; i < sizeOne; i++) {
// Cleared on each pass
temp[0] = 0;
for (j = 0; j < sizeTwo; j++) {
double v = similarity(PyOne[i], PyTwo[j]);
if (v > 4) {
// Works with the temp buffer
strcat(temp, (PyOne[i]));
strcat(temp, (";"));
int size = strlen(temp) + 1; //+1 for null termination
char * str = malloc(size);
memcpy(str, temp, size);
str[size-1] = 0; //Null termination
matches[i] = str;
}
}
}
return matches;
free_list(matches, sizeOne);
}
#In Python
dll = CDLL("c.file")
dll.mainForLoop.argtypes = POINTER(c_char_p),POINTER(c_char_p),c_size_t,c_size_t
dll.mainForLoop.restype = POINTER(c_char_p)
dll.free_list.argtypes = POINTER(c_char_p),c_size_t
dll.free_list.restype = None
def make_clist(lst):
return (c_char_p * len(lst))(*[x.encode() for x in lst])
def mainForLoop(list1,list2):
size = c_size_t()
result = dll.mainForLoop(make_clist(list1),make_clist(list2),len(list1),len(list2))
data = [x.decode() for x in result[:size.value]]
dll.free_list(result,size.value)
return data
list1 = ["Apple", "Orange", "Banana"]
list2 = ["Apple", "Mango", "Pineapple", "Apple"]
print(mainForLoop(list1,list2))
//在C中
#包括
#包括
#包括
#包括
无效自由列表(字符**列表,大小){
对于(size_t i=0;i4){
//使用临时缓冲区
strcat(temp,(PyOne[i]);
标准温度(“;”);
int size=strlen(temp)+1;//+1表示空终止
char*str=malloc(大小);
memcpy(str、temp、size);
str[size-1]=0;//空终止
匹配[i]=str;
}
}
}
返回比赛;
免费列表(匹配项,sizeOne);
}
#用Python
dll=CDLL(“c.file”)
dll.mainForLoop.argtypes=指针(c_char_p)、指针(c_char_p)、c_size_t、c_size_t
dll.mainForLoop.restype=指针(c_char_p)
dll.free\u list.argtypes=指针(字符),大小
dll.free_list.restype=None
def make_clist(lst):
返回(c_char_p*len(lst))(*[x.encode()表示lst中的x])
def mainForLoop(列表1、列表2):
尺寸=c_尺寸_t()
result=dll.mainForLoop(make_clist(list1)、make_clist(list2)、len(list1)、len(list2))
数据=[x.decode()表示结果中的x[:size.value]]
dll.free_列表(结果、大小、值)
返回数据
列表1=[“苹果”、“橘子”、“香蕉”]
列表2=[“苹果”、“芒果”、“菠萝”、“苹果”]
打印(mainForLoop(列表1、列表2))
然而,这返回:
[]
请注意,C中的“comparison()”函数是一个字符串距离计算,它通过比较两个字符串返回一个双精度值
非常感谢您的帮助。这里有一个比您的配置更接近的示例。请注意,我的
main
函数仅用于运行示例,在您的情况下,它将是无用的
主要的修复方法是,我为每个新字符串分配内存,而您没有这样做(您为指针分配了内存,但没有为字符串本身分配内存)。为此,我首先在堆栈上使用一个100个字符的临时缓冲区(如果需要的话,可以使其更长),一旦知道字符串的长度,我就分配它(请注意,您为释放这些字符串和指针准备的函数(free_list)已经正确):
#包括
#包括
#包括
#包括
双重比较(常量字符*1,常量字符*2){
int try=rand()%12;
返回尝试;
}
char**mainForLoop(char**PyOne,char**PyTwo,int-sizeOne,int-sizewo){
尺寸i=0;
尺寸j=0;
//分配一个由N个字符串指针组成的数组,其中N是PyOne的大小
char**matches=malloc(sizeOne*sizeof(char*);
//临时缓冲区
字符温度[100]={0};
对于(i=0;i4){
//使用临时缓冲区
strcat(temp,(PyOne[i]);
标准温度(“;”);
int size=strlen(temp)+1;//+1表示空终止
//然后分配一个大小正确的字符串
char*str=malloc(大小);
memcpy(str、temp、size);
str[size-1]=0;//空终止
//并收集它
匹配[i]=str;
}
}
}
返回比赛;
}
无效自由列表(字符**列表,大小){
对于(size_t i=0;i 对于(char i=0;i而言,提供的C代码不正确,因此下面是演示如何传递和返回字节数组的示例。此示例只是将这两个列表附加在一起。它还处理释放内存的问题,因此C中的内存分配不会导致内存泄漏
测试c:
\ifdef\u WIN32
#定义API_uudeclspec(dllexport)
#否则
#定义API
#恩迪夫
#包括
#包括
API字符**附加列表(常量字符**列表1,大小大小1,常量字符**列表2,大小2,大小*pSize){
字符**总数=malloc((大小1+大小2)*大小
// In C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void free_list(char** list, size_t size) {
for(size_t i = 0; i < size; ++i) if (list[i]) free(list[i]);
free(list);
}
char ** mainForLoop(const char ** PyOne, const char ** PyTwo, size_t sizeOne, size_t sizeTwo) {
size_t i = 0;
size_t j = 0;
char ** matches = malloc(sizeOne * sizeof(char *));
char temp[100] = {0};
for (i = 0; i < sizeOne; i++) {
// Cleared on each pass
temp[0] = 0;
for (j = 0; j < sizeTwo; j++) {
double v = similarity(PyOne[i], PyTwo[j]);
if (v > 4) {
// Works with the temp buffer
strcat(temp, (PyOne[i]));
strcat(temp, (";"));
int size = strlen(temp) + 1; //+1 for null termination
char * str = malloc(size);
memcpy(str, temp, size);
str[size-1] = 0; //Null termination
matches[i] = str;
}
}
}
return matches;
free_list(matches, sizeOne);
}
#In Python
dll = CDLL("c.file")
dll.mainForLoop.argtypes = POINTER(c_char_p),POINTER(c_char_p),c_size_t,c_size_t
dll.mainForLoop.restype = POINTER(c_char_p)
dll.free_list.argtypes = POINTER(c_char_p),c_size_t
dll.free_list.restype = None
def make_clist(lst):
return (c_char_p * len(lst))(*[x.encode() for x in lst])
def mainForLoop(list1,list2):
size = c_size_t()
result = dll.mainForLoop(make_clist(list1),make_clist(list2),len(list1),len(list2))
data = [x.decode() for x in result[:size.value]]
dll.free_list(result,size.value)
return data
list1 = ["Apple", "Orange", "Banana"]
list2 = ["Apple", "Mango", "Pineapple", "Apple"]
print(mainForLoop(list1,list2))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
double comparison(const char * one, const char * two) {
int try = rand() % 12;
return try;
}
char ** mainForLoop(char ** PyOne, char ** PyTwo, int sizeOne, int sizeTwo) {
size_t i = 0;
size_t j = 0;
// Allocate an array of N string pointers where N is the size of PyOne
char ** matches = malloc(sizeOne * sizeof(char *));
// The temporary buffer
char temp[100] = {0};
for (i = 0; i < sizeOne; i++) {
// Cleared on each pass
temp[0] = 0;
for (j = 0; j < sizeTwo; j++) {
double v = comparison(PyOne[i], PyTwo[j]);
if (v > 4) {
// Works with the temp buffer
strcat(temp, (PyOne[i]));
strcat(temp, (";"));
int size = strlen(temp) + 1; //+1 for null termination
// Then allocates a string of the right size
char * str = malloc(size);
memcpy(str, temp, size);
str[size-1] = 0; //Null termination
// And collects it
matches[i] = str;
}
}
}
return matches;
}
void free_list(char** list, size_t size) {
for(size_t i = 0; i < size; ++i) if (list[i]) free(list[i]);
free(list);
}
int main() {
// Initializes random
srand(time(0));
int N = 3;
char * PyOne[3] = {"Apple", "Orange", "Banana"};
char * PyTwo[4] = {"Cucumber", "Mango", "Pineapple", "Apple"};
char ** matches = mainForLoop(PyOne, PyTwo, N, 4);
// Prints the result which is possibly (depending on random) :
// "Apple; Orange; Banana;Banana;"
for (char i=0; i<N; i++) printf("%s ", matches[i]);
printf("\n");
// Frees
free_list(matches, N);
return 0;
}