Изменяемые значения являются результатом вашего кода C. Значение N, которое вы вычисляете, неверно, sizeof(arr1)
сообщает вам размер байта указателя, а не количество элементов в нем. В вашем коде вы используете байты в вашем коде и байты, которые хранятся после массивов в памяти. Как отметил @Mathias Schmid в комментариях, вы должны добавить N в качестве параметра.
Вот код C:
#include <stdio.h>
#include <math.h>
extern "C"{
float get_mod(float *array, unsigned int N){
int i;
float mod=0;
for(i=0;i<N;i++){
mod=mod+pow(array[i],2);
}
mod=sqrt(mod);
return mod;
}
float get_inner(float *array1,float * array2, unsigned int N){
int i;
float inner=0;
for(i=0;i<N;i++){
inner = inner+array1[i]*array2[i];
}
return inner;
}
int cos_sim(float *a,float *b, unsigned int N){
float mod1;
float mod2;
float inner;
float cs;
float result;
int res;
mod1=get_mod(a, N);
mod2=get_mod(b, N);
inner=get_inner(a,b, N);
cs=inner/(mod1*mod2);
result=cs*pow(10,3);
res=result;
printf("%d\n",res);
return res;
}
}
В Python я бы рекомендовал просто использовать import ctypes
или from ctypes import *
. Сначала это меня немного смутило. Я также обновил ваш код Python:
import ctypes
import numpy as np
import win32api
dll = ctypes.CDLL(r"E:\whywork\zldf\cosine_similarity_c.so")
cossim=dll.cos_sim
arr1 = np.array([1,2,3],dtype="float32")
arr2 = np.array([1,2,5],dtype="float32")
N = ctypes.c_uint(len(arr1))
result = cossim(arr1.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
arr2.ctypes.data_as(ctypes.POINTER(ctypes.c_float)), N)
win32api.FreeLibrary(dll._handle)
print(result)
Когда я запускаю этот код, результат всегда одинаков (975
)