Accessing contents of an object returned by DLL us

2019-08-30 00:40发布

问题:

The dll returns an object on calling a function using ctypes in python.

It returns the following - say it is named as ReturnO; print(ReturnO) gives the following:

(63484, <DLLname.ClassName object at 0x09D35670>)

The object should return the parameters; their names are: Paramater_1, Parameter_2 and so on. My question is, how do i access the values in Parameter_1, Parameter_2 etc.

if i do a print as follows

print(ClassName.Parameter_1)
print(ClassName.Parameter_2)

i get the following

 Field type=c_float_Array_5, ofs=49483, size=20
 Field type=c_float_Array_5, ofs=49503, size=20

Now, how do I get the value in this array. dotValue (.value) does not work.

Appreciate you help. Thank you.

----------------ADDED/MODIFIED----------BELOW------------

below is the code; appreciate your help:

num1=10.1234
int1=10
num11=1.1111
str1=”abcd”

ret=GetOutput_Main(int1,num1,num11,str1)

class ClassName(ctypes.Structure):
  _pack_ = 1
  _fields_ = [("parameter_1", ctypes.c_float * 5),
              ("parameter_2", ctypes.c_float * 5)]

def GetOutput_Main (int2,num2,num22,str2):
    lib = ctypes.WinDLL("mydllname.dll")
    prototype = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ClassName))
    paramflags = (1, "int2",), (1, "num2",), (2, "num22",), (2, "str2",),
    Getoutput_Sub = prototype(("Getoutput", lib), paramflags))
    ret = Getoutput_Sub(int2,num2)
    print(ret) #gives the details of the object
    print(str2.parameter_1) #gives the details of array

the print(ret) gives me:

(63484, <mydllname.ClassName object at 0x09D35670>)

if i do print(str2), I get the following:

<class 'mydllname.ClassName'>

and print(str2.parameter_1) gives me

Field type=c_float_Array_5, ofs=49483, size=20

i am looking for ways to unpack the object, thanks.

if I do, where num22 is the size

UnpackedST = struct.unpack(str2,num22)

i get the following error

Struct() argument 1 must be a str or bytes object, not _ctypes.PyCStructType

回答1:

Given your description it looks like you have a C function similar to the following:

#include <inttypes.h>

#define API __declspec(dllexport)

struct ClassName
{
    float parameter_1[5];
    float parameter_2[5];
};

API int __stdcall Getoutput(int a, uint32_t b, uint32_t* pc, struct ClassName* pd)
{
    int i;
    *pc = a+b;
    for(i=0;i<5;++i)
    {
        pd->parameter_1[i] = i*.5f;
        pd->parameter_2[i] = i*.25f;
    }
    return a*b;
}

Your paramflags argument indicates two inputs (type 1) and two return values (type 2). Simply pass the two required input values, then index the second return value to access its members. Use list() to convert the array to Python lists:

from ctypes import *

class ClassName(Structure):
  _fields_ = [('parameter_1',c_float * 5),
              ('parameter_2',c_float * 5)]

lib = WinDLL('test')
prototype = WINFUNCTYPE(c_int,c_int,c_uint32,POINTER(c_uint32),POINTER(ClassName))
paramflags = (1,'int2'),(1,'num2'),(2,'num22'),(2,'str2')
Getoutput = prototype(('Getoutput',lib),paramflags)

ret = Getoutput(10,11)
print(ret)
print(ret[1].parameter_1)
print(ret[1].parameter_2)
print(list(ret[1].parameter_1))
print(list(ret[1].parameter_2))

Output:

(21, <__main__.ClassName object at 0x000001DA3A9139C8>)
<__main__.c_float_Array_5 object at 0x000001DA3A790EC8>
<__main__.c_float_Array_5 object at 0x000001DA3A790EC8>
[0.0, 0.5, 1.0, 1.5, 2.0]
[0.0, 0.25, 0.5, 0.75, 1.0]


回答2:

If you have a ctypes float array, there are various means to get each of the float.

Example:

We start with a simple python float list, just for the sake of the demo:

>>> python_float_list = [1.5, 2.5, 3.5, 4.5, 5.5]  

Create a ctypes float array from the list:

>>> import ctypes
>>> c_float_array = (ctypes.c_float * 5)(*python_float_list)
>>> c_float_array
<__main__.c_float_Array_5 object at 0x000001D6D9A66A48>

ctypes arrays are subscriptable:

>>> c_float_array[0]
1.5
>>> c_float_array[1]
2.5

You can use a for loop on them too:

>>> for f in c_float_array:
    print(f)


1.5
2.5
3.5
4.5
5.5

As the ctypes arrays are subscriptable, you can get a python list back from them:

>>> list(c_float_array)
[1.5, 2.5, 3.5, 4.5, 5.5]