nmahale.10
nmahale.10

Reputation: 31

passing structure from c++ to python

C++ code

typedef struct Box
{
   public:
      int length;   // Length of a box
      int breadth;  // Breadth of a box
      int height;   // Height of a box
};

extern "C"
{
    //struct Box __declspec(dllexport) GetAllInfo();
    TESTAPI struct Box * GetAllInfo();
}

extern "C"
{
    TESTAPI struct Box * GetAllInfo()
    {
       Box *Box1 = new Box;
       Box1->height = 5;
       Box1->length = 6;
       Box1->breadth = 7;

       cout << "Info is : " << Box1->height<<Box1->length<<Box1->breadth <<endl;

       return Box1;
   }
}

Python code

import ctypes
from ctypes import Structure, c_int, c_double, windll
from ctypes import *
from ctypes import wintypes
from collections import namedtuple

#astdll = windll.CDll
class Box(object):

    def __init__(self,height,length,breadth):

        self.height = height
        self.length = length
        self.breadth = breadth

#class Box(Structure):

# _fields_ = [

# ("height", ctypes.c_int),
# ("length", ctypes.c_int),
# ("breadth", ctypes.c_int)

# ]

Box = namedtuple("Box", "height length breadth")

lib = cdll.LoadLibrary("F:\\QT SCADA\\forPythonDLL\\Neha_Test\\Debug\\Neha_Test.dll")

#lib.GetAllInfo.restype = POINTER(Box)

s = Box

global result

result = lib.GetAllInfo()

#s = result
s.height = 20

print (result.height)
print (s.height)

This is the error:

Running script: "C:\Users\Administrator\Desktop\test.py"

Info is : 567

Traceback (most recent call last):

File "C:\Users\Administrator\Desktop\test.py", line 41, in

print (result.height)

AttributeError: 'int' object has no attribute 'height'

Upvotes: 1

Views: 3304

Answers (3)

nmahale.10
nmahale.10

Reputation: 31

Thanks fr all the help....:)

I got this code

its working fine

import ctypes
from ctypes import Structure, c_int, c_double, windll
from ctypes import *
from ctypes import wintypes
from collections import namedtuple


lib = cdll.LoadLibrary(DLL_PATH)

class Box(Structure):
_fields_ = [
    ("length", c_int),
    ("breadth", c_int),
    ("height", c_int)]

 lib.GetAllInfo.restype = POINTER(Box)
result = lib.GetAllInfo()
print ("result type: ", type(result))
print ("-"*30)
print ("result: ",result)
print ("-"*30)
print (result.contents)

Box1=result[0]
print(Box1.height)

Upvotes: 2

Tim
Tim

Reputation: 1527

You are mixing C and C++. Your updated code works because ctypes.Structure fixes this issue for you. You need to also release the memory you allocate. How you do this depends on what your program needs to do with a Box. One possibility is to use an in/out parameter in GetAllInfo (implementation left as an exercise for the reader).


struct Box {
    int length;   // Length of a box
    int breadth;  // Breadth of a box
    int height;   // Height of a box
};

extern "C" TESTAPI Box* GetAllInfo() {
    Box *Box1 = new Box;
    Box1->height = 5;
    Box1->length = 6;
    Box1->breadth = 7;

    cout << "Info is : " << Box1->height << Box1->length << Box1->breadth << endl;
    return Box1;
}

Upvotes: 0

bawjensen
bawjensen

Reputation: 128

Not 100% sure on this, but at a guess I'd say your issues lies in the fact that the C++ code for GetAllInfo returns a Box pointer (type Box*), which is effectively just an integer referring to a location in memory. You're then trying to get the height attribute of this integer pointer, which is resulting in the error AttributeError: 'int' object has no attribute 'height'.

Try returning a Box object (as below), not a Box pointer, and see if that fixes it.

TESTAPI struct Box * GetAllInfo()
{
   Box *Box1 = new Box;
   Box1->height = 5;
   Box1->length = 6;
   Box1->breadth = 7;

   cout << "Info is : " << Box1->height<<Box1->length<<Box1->breadth <<endl;

   return Box1;
}

becomes

TESTAPI struct Box GetAllInfo()
{
   Box *Box1 = new Box;
   Box1->height = 5;
   Box1->length = 6;
   Box1->breadth = 7;

   cout << "Info is : " << Box1->height<<Box1->length<<Box1->breadth <<endl;

   return (*Box1);
}

Upvotes: 0

Related Questions