Saya ingin meneruskan alamat buffer array numpy ke fungsi c, fungsi C saya terlihat seperti:

void print_float_buff(void *buff)
{
    float *b = (float *)buff;
    printf("Float Data: %f, %f, %f,\n", b[0], b[1], b[2]);
}

Dalam python kode saya adalah:

import numpy as np
fun=ctypes.CDLL("./mylib.so")
l = np.array([10., 12.6, 13.5], dtype = 'float')
address, flag = l.__array_interface__['data']
fun.print_float_buff(ctypes.c_void_p(address))

A saya mendapatkan data yang sama sekali berbeda dalam fungsi c saya. Alamat sepertinya tidak bagus. Bagaimana saya bisa memberikan alamat yang benar ke fungsi C saya? Terima kasih.

0
coolgoose 8 Mei 2021, 09:51

2 jawaban

Jawaban Terbaik

Saya menemukan masalahnya. Di c, ukuran float adalah empat byte sedangkan di python ukuran float adalah 8 byte. Jika saya mengalokasikan array seperti ini:

l = np.array([10., 12.6, 13.5], dtype = 'float32')

Itu bekerja dengan baik.

0
coolgoose 8 Mei 2021, 07:01

Jika Anda menentukan .argtypes dengan benar, ctypes akan memberi tahu Anda bahwa jenisnya salah. Di bawah ini memerlukan array satu dimensi yang kompatibel dengan c_float:

Tes.c

#include <stdio.h>

#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

API void print_float_buff(float *buff, size_t size)
{
    for(size_t i = 0; i < size; ++i)
        printf("buff[%zu] = %f\n",i,buff[i]);
}

Test.py

from ctypes import *
import numpy as np

dll = CDLL('./test')
dll.print_float_buff.argtypes = np.ctypeslib.ndpointer(c_float,ndim=1),c_size_t
dll.print_float_buff.restype = None

a = np.array([10., 12.6, 13.5])
dll.print_float_buff(a,len(a))

Keluaran:

Traceback (most recent call last):
  File "C:\test.py", line 9, in <module>
    dll.print_float_buff(a,len(a))
ctypes.ArgumentError: argument 1: <class 'TypeError'>: array must have data type float32

Mengubah array seperti yang disarankan:

a = np.array([10., 12.6, 13.5],dtypes='float32')

Keluaran:

buff[0] = 10.000000
buff[1] = 12.600000
buff[2] = 13.500000
1
Mark Tolonen 8 Mei 2021, 20:04