开发者

Writing a Python wrapper for difficult C header file using Cython

开发者 https://www.devze.com 2023-02-20 09:33 出处:网络
A while back I wrote an thin wrapper around a commercial DAQ library using ctypes.Since then I\'ve come across Cython and wanted to give

A while back I wrote an thin wrapper around a commercial DAQ library using ctypes. Since then I've come across Cython and wanted to give it a go, thinking it might make it better/cleaner all around than what I had before. Most of the Cython documentation makes sense, and I've found most of what I know but the library I'm wrapping is highly windows specific and does things a little different 开发者_开发知识库than standard C/C+ + code, at least as far as I can tell.

Here's a couple of snippets from the header file, that I'm not exactly sure how to wrap.


#ifndef DAQ_H
#define DAQ_H

#ifdef   __cplusplus
extern "C" {
#endif

#if !defined(_DAQAPI32_)
  #define  DAQAPI   __declspec(dllimport)
#else
  #define  DAQAPI
#endif

From what I gather, I probably can ignore most of this in my cython definition? I've tried compiling C code with gcc, but it throws errors at every function definition. With ctypes I accessed the library directly, and did not use the header file at all.


/* Handle Type Definition */
typedef  INT   DaqHandleT;

/* Initialization and Locking Prototypes */
DAQAPI DaqHandleT WINAPI   daqOpen(LPSTR daqName);
DAQAPI DaqError WINAPI     daqClose(DaqHandleT handle);
DAQAPI DaqError WINAPI     daqOnline(DaqHandleT handle, PBOOL online);

/* Error Handler Type Definitions */
typedef VOID CALLBACK      DaqErrorHandlerFT(DaqHandleT handle,
DaqError errCode);
typedef DaqErrorHandlerFT  *DaqErrorHandlerFPT;

/* Error Handler Function Prototypes */
DAQAPI DaqError WINAPI  daqSetDefaultErrorHandler(DaqErrorHandlerFPT
handler);
DAQAPI DaqError WINAPI  daqSetErrorHandler(DaqHandleT handle,
DaqErrorHandlerFPT handler);
DAQAPI DaqError WINAPI  daqProcessError(DaqHandleT handle, DaqError
errCode);
DAQAPI DaqError WINAPI  daqGetLastError(DaqHandleT handle, DaqError
*errCode);
DAQAPI VOID CALLBACK    daqDefaultErrorHandler(DaqHandleT handle,
DaqError errCode);
DAQAPI DaqError WINAPI  daqFormatError(DaqError errorNum, PCHAR msg);

This is basically how most functions are declared and operate. They only return error codes, all important information to get out of it is done through pointers. I couldn't find anything in the documentation on how to work with pointers for return types, I probably didn't look hard enough.

Can anyone point me in the right direction for wrapping these sorts of functions?

Things like DaqError are actually enums declared in the header file, they go abit enum crazy in this library, some 1500 lines of it.

Thanks for any help,


Create a cython typedef with the return type. In this way cython will use the same Macros of original library.

cdef extern from "header.h":

    ctypedef void * win_api_t "DAQAPI DaqHandleT WINAPI"
    win_api_t daqOpen( char* )  

cpdef pyDaqOpen( pystr ):
    daqOpen(pystr)
0

精彩评论

暂无评论...
验证码 换一张
取 消