简体   繁体   中英

Calling C++ Method from Python using ctypes not working

I am trying to interact with a dll from python using ctypes, reading the documentation the C++ method signature is of the following:

my_c_pp_function(user *param1[],const int_8 param2,const int_8 values3[],const int_8 length_param1)

Essentially the c++ function requires a list of users, an integer,a list of values and the number of users, also an integer

Note: the users is a structure containing name,age, and id. Something like:

typedef struct
{
char name[255];
int_16 age;
int_32 uid;
}user;

When I try calling this function from python code using ctypes I do:

def call_my_c_pp_function(list_of_users,int_param2,list_of_values,int_lenght_of_list):


        myparam1=(ctypes.c_char_p * len(list_of_users))(*list_of_users)
        myparam2=ctypes.c_int8(int_param2)
        myparam3=(ctypes.c_int8 * len(list_of_values))(*list_of_values)
        myparam4=ctypes.c_int8(int_lenght_of_list)

    self.dll_object.my_c_pp_function.argtypes(ctypes.POINTER(ctypes.c_char_p),ctypes.c_int8,ctypes.POINTER(ctypes.c_int8),ctypes.c_int8)

        ret_value=self.dll_object.my_c_pp_function(myparam1,myparam2,myparam3,myparam4)

Now every time I call the python function I get an error basically if the function succeeds the return value should be 0, any non zero number indicates some kind of problem.

I keep getting a large non-zero number as the return value. What could I possibly be doing wrong? is the way I'm creating the array of users, and the array of values wrong?

I am not sure how to populate/make use of the c++ user structure in my python code so that my list is not just a list of strings but a list of users

I'm using Python2.7 on Windows

Regards

Assuming that you cannot change the signature of your library function.

I would recommend you to create a simple adapter for your c++ function, which just acts as an interface to your actual function. This function would just take all the values you need and then convert them to your needed types.

Here is a working example (tested with python27). Note that I added an additional parameter for the number of elements in the int array.

py_caller.py

import ctypes
import os


class user(ctypes.Structure):
    _fields_ = [("name", ctypes.c_char_p),
                ("age", ctypes.c_int),
                ("uid", ctypes.c_int)]


def create_users(count):
    users = (user * count)()
    for i in range(count):
        users[i].name = ctypes.c_char_p("user" + str(i))
        users[i].age = i
        users[i].uid = i * i
    return users


def create_values(count):
    values = (ctypes.c_int * count)()
    for i in range(count):
        values[i] = i ** 2
    return values


def main():
    os.environ['PATH'] += ";" + os.path.dirname(os.path.abspath(__file__))
    dll = ctypes.cdll.LoadLibrary('cppdll')

    count = 4
    users = create_users(count)
    n_users = ctypes.c_int(count)

    values = create_values(count)
    n_values = ctypes.c_int(count)

    some_int = ctypes.c_int(42)

    res = dll.func(users, n_users, some_int, values, n_values)
    print (res)


if __name__ == "__main__":
    main()

export.h

#pragma once

typedef struct t_user
{
  char *name;
  int age;
  int uid;
};

extern "C" __declspec(dllexport) int func(t_user *users, int n_users, int val, int *values, int n_values);

export.cpp

#include "export.h"
#include <iostream>

int func(t_user *users, int n_users, int val, int *values, int n_values)
{
  std::cout << "users:\n";
  for (auto i = 0; i < n_users; ++i)
  {
    std::cout << users[i].name
      << ": " << users[i].age 
      << " - " << users[i].uid << "\n";
  } 

  std::cout << "values:\n";
  for (auto i = 0; i < n_values; ++i)
    std::cout << values[i] << "\n";

  std::cout << "some int: " << val << "\n";

  // do something else with the values
  // such as calling your actual library function

  return 1;
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM