Ctypes,将指针传递给枚举,接收 uint_32

Ctypes, Passing pointer to enum, receiving uint_32

我正在尝试传递一个指向枚举的指针。我在这里 [ctypes 结构 ][1] 找到了 ctypes 和枚举的教程,但我的应用程序有点不同。 我的 DLL 的伪代码如下所示

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

#ifdef SOME_API_EXPORTS
#define SOME_API __declspec(dllexport)
#else
#define SOME_API __declspec(dllimport)
#endif

typedef enum   
{
    off,
    on    
} MyEnum;

SOME_API int32_t get_param(MyEnum* param1)
{
    int status = error;
    if (param1 == NULL)
    {
        return status;
    }
    //do some processing
    status = done;
    return status;
}

我在 python 中所做的与此类似:

    import ctypes
    from enum import IntEnum
   
    test = ctypes.WinDLL('Project.dll')
    
    if (test == 0):
        print( " Could not open DLL")
    
    class CtypesEnum(IntEnum):
        @classmethod
        def from_param(cls, obj):
            return int(obj) 
    
    class myEnum(CtypesEnum):
    
        off = 0                
        on = 1                     
    
    
    getParam = test.get_param
    getParam.argtypes = [ctypes.POINTER(ctypes.c_int)]
    getParam.restype= ctypes.c_uint
    getParam(myEnum.on)

The error I get now is

     Traceback (most recent call last):
      File "<pyshell#5>", line 1, in <module>
        getParam(myEnum.on)
    ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected LP_c_long instance instead of myEnum

What's the correct way of passing an enum pointer using ctypes.I couldn't find an example and I'm kinda new to python :/

  [1]: https://v4.chriskrycho.com/2015/ctypes-structures-and-dll-exports.html

这是我对 python 部分的解决方案。我分别读了1和0。

import ctypes
from ctypes import *

test = ctypes.WinDLL('Project.dll')

if (test == 0):
    print( " Could not open DLL")
 
class myEnum(c_int):

    off = 0                
    on = 1

    
getParam = test.get_param
getParam.argtype =  myEnum()
getParam.restype= ctypes.c_int
result = test.get_param(myEnum.on)
print(result)
result = test.get_param(myEnum.off)
print(result)

Listing [Python.Docs]: ctypes - A foreign function library for Python.
As I stated in my comment, the 1st error is (most likely) the same thing as ,然后在编辑之后,弹出另一个(发生在before the 1st)。
这是摆脱所有的方法。

dll00.c:

#include <stdio.h>
#include <stdint.h>

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


typedef enum {
    Off,
    On,
} Enum;


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

DLL00_EXPORT_API int32_t get_param(Enum *pparam);

#if defined(__cplusplus)
}
#endif


int32_t get_param(Enum *pparam) {
    int status = -1;
    if (pparam == NULL) {
        printf("NULL arg\n");
        return status;
    }
    printf("C - arg: %d\n", *pparam);
    if (pparam == NULL) {
        return status;
    }
    //do some processing
    status = 1;
    return status;
}

code00.py:

#!/usr/bin/env python

import sys
import ctypes as ct
from enum import IntEnum


DLL_NAME = "./dll00.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")


class CtypesEnum(IntEnum):
    @classmethod
    def from_param(cls, obj):
        return int(obj)


class OOEnum(CtypesEnum):
    Off = 0
    On = 1



def main(*argv):
    dll = ct.CDLL(DLL_NAME)  # Use ct.WinDLL for Win 32bit
    get_param = dll.get_param
    get_param.argtypes = (ct.POINTER(ct.c_int),)
    get_param.restype = ct.c_int

    for en in [
        OOEnum.Off,
        OOEnum.On,
    ]:
        get_param(ct.pointer(ct.c_int(en.value)))


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

输出:

[cfati@cfati-5510-0:/mnt/e/Work/Dev/Whosebug/q068826175]> ~/sopr.sh
### Set shorter prompt to better fit when pasted in Whosebug (or other) pages ###

[064bit prompt]> ls
code00.py  dll00.c
[064bit prompt]> 
[064bit prompt]> gcc -shared -m64 -fPIC -o dll00.so dll00.c
[064bit prompt]> ls
code00.py  dll00.c  dll00.so
[064bit prompt]> 
[064bit prompt]> ${PY_VENVS_HOME}/py_pc064_03_08_test0/bin/python code00.py 
Python 3.8.10 (default, Jun  2 2021, 10:49:15) [GCC 9.4.0] 064bit on linux

C - arg: 0
C - arg: 1

Done.

Win 上的情况相同,只有构建(和 运行)命令不同。