簡體   English   中英

將 char* 數組從 c dll 傳遞到 python

[英]Pass char* array from c dll to python

我有簡單的 dll 和 function ,它將回調作為參數並調用它有時傳遞 unsigned char* 數組。 我想在 python 中使用它。

這是 dll 來源:

typedef void (*buffer_ready_callback_t)(unsigned char* data, int len);

extern "C" void __declspec(dllexport) example(buffer_ready_callback_t cb) {
     unsigned char* data = (unsigned char*)malloc(100);
     memset(data,0xAA,100);
     
     cb(data,100);

     free(data);
}

在 python 我這樣使用它:

library = cdll.LoadLibrary("example.dll")
buffer_ready_callback_t = CFUNCTYPE(None, c_char_p, c_int, c_ulong)

def api_callback_buffer(self, data, ln, ts):    
        #problem here
        pass

function = self.library.example
function.restype = None
function.argtypes = [buffer_ready_callback_t]
api_buffer_cb = buffer_ready_callback_t(api_callback_buffer)        
function(api_buffer_cb);

那么問題是如何使用回調 function 中收到的數據? 是否可以轉換為字節數組或列表或 numpy 數組或其他可用於 python 的數組?

謝謝

清單[Python.Docs]:ctypes - 用於 Python 的外部 function 庫

這個問題有點不清楚。 給定現有代碼,您應該已經在回調 function 中將數據作為字節保存。

這是一個例子。

dll00.c

#include <stdio.h>
#include <stdlib.h>

#if defined(_WIN32)
#  define DLL00_EXPORT_API __declspec(dllexport)
#else
#  define DLL00_EXPORT_API
#endif


typedef void (*Callback)(unsigned char *pData, int len);

#if defined(__cplusplus)
extern "C" {
#endif

DLL00_EXPORT_API void dll00Func00(Callback cb, unsigned int len, unsigned char fillValue);

#if defined(__cplusplus)
}
#endif


void dll00Func00(Callback cb, unsigned int len, unsigned char fillValue) {
    unsigned char *pData = malloc(len);
    memset(pData, fillValue, len);
    cb(pData, len);
    free(pData);
    pData = NULL;
}

代碼00.py

#!/usr/bin/env python

import sys
import ctypes as ct


CharArray = ct.POINTER(ct.c_char)  # #1: Use ct.POINTER(ct.c_char) instead of ct.c_char_p as 2nd arg type
#CharArray = ct.c_char_p
Callback = ct.CFUNCTYPE(None, CharArray, ct.c_int)

DLL_NAME = "./dll00.dll"

DATA_LEN = 0x100


def func(data, length):
    print("Length: {0:d}".format(length))
    print(type(data))
    print("Elements:")
    for idx in [0, DATA_LEN - 1]:
        print("  {0:3d} - {1:}".format(idx, data[idx]))
    b = b"".join((data[i] for i in range(length)))
    print(type(b), len(b), b)


def main(*argv):
    dll00 = ct.CDLL(DLL_NAME)
    dll00Func00 = dll00.dll00Func00
    dll00Func00.argtypes = (Callback, ct.c_uint, ct.c_ubyte)
    dll00Func00.restype = None

    dll00Func00(Callback(func), DATA_LEN, 0xAA)  # #2: Pass 0x00 as 3rd arg and uncomment line #8, and you'll see what I meant in the 1st note


if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main(*sys.argv[1:])
    print("\nDone.")

Output

 [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q063190506]> sopr.bat *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [prompt]> "c:\Install\pc032\Microsoft\VisualStudioCommunity\2017\VC\Auxiliary\Build\vcvarsall.bat" x64 ********************************************************************** ** Visual Studio 2017 Developer Command Prompt v15.9.25 ** Copyright (c) 2017 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x64' [prompt]> dir /b code00.py dll00.c [prompt]> cl /nologo /MD /DDLL dll00.c /link /NOLOGO /DLL /OUT:dll00.dll dll00.c Creating library dll00.lib and object dll00.exp [prompt]> dir /b code00.py dll00.c dll00.dll dll00.exp dll00.lib dll00.obj [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Length: 256 <class 'ctypes.LP_c_char'> Elements: 0 - b'\xaa' 255 - b'\xaa' <class 'bytes'> 256 b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa' Done.

備注

  • c_char_p將與NUL終止的字符串一起使用,在這里使用它是不正確的(即使顯然一切看起來都不錯)
  • 這個例子有點復雜(為了方便地舉例說明上一個項目符號)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM