Python调用C语言时,return值异常

When Python calls C language, the return value is abnormal

Python调用C语言时,return值异常(python3.6.5调用gcc)

我试图将列表传递给 C.so 文件和 return 一个值。我用C语言测试没问题,但是用python调用c.so文件时returned的值总是变,有时return的值甚至变成负值。

//part c
#include <stdio.h>
#include <math.h>

extern c;

float get_mod(float *array){
    int N=sizeof(array);
    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){
    int N;
    N=sizeof(array1);
    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){
    float get_mod(float *);
    float get_inner(float *,float *);

    float mod1;
    float mod2;
    float inner;
    float cs;

    mod1=get_mod(a);
    mod2=get_mod(b);
    inner=get_inner(a,b);
    cs=inner/(mod1*mod2);
    float result;
    result=cs*pow(10,3);

    int res=result;
    printf("%d\n",res);
    return res;
}

//part python
import ctypes
from ctypes import *
import numpy as np
import win32api

dll = ctypes.CDLL(r"E:\whywork\zldf\cosine_similarity_c.so")
cossim=dll.cos_sim
cossim.argtypes=[POINTER(c_float),POINTER(c_float)]
arr1 = np.array([1,2,3],dtype="float64")
arr2 = np.array([1,2,5],dtype="float64")
cossim.restype=c_int
result = cossim(arr1.ctypes.data_as(POINTER(c_float)),arr2.ctypes.data_as(POINTER(c_float)))
win32api.FreeLibrary(dll._handle)
print(result)

我想知道Python调用C

时如何设置return值

变化的值是您的 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 ctypesfrom 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)