c++ - Python lists and ctypes -


hi trying call c++ function has following signature

change_mountain_heights(mnt *mountains[],float32 heights[],int8 num_elements) 

the idea being python can have list of mountains , heights, , can call c++ function set heights. c++ function takes 2 arrays. array mountain names , array mountain heights.

so in python have 2 lists

  • mountains=[kilimanjaro,mount_saina,mount_elgon]
  • mnt_heights=[100.1,200,3331.56]
  • element_count=len(mountains)

i use ctypes , call c-function follows,

def change_heights(mountain_list,height_list,element_count):     mountain_array=(ctypes.c_char_p * len(mountain_list))(*mountain_list)     height_array=(ctypes.c_float * len(height_list))(*height_list)     element_count_param=ctypes.c_int8(element_count)     change_mountain_heights.argtypes=(ctypes.c_char_p,ctypes.c_float,ctypes.c_int8)     _success=change_mountain_heights(mountain_array,height_array,element_count_param) 

but doesn't seem work, not 100% sure if creating array correctly in both size and making sure mountain strings assigned array, heights. doing wrong, or should elsewhere source of issue?

update

i think 1 of issues stems from

    change_mountain_heights.argtypes=(ctypes.c_char_p,ctypes.c_float,ctypes.c_int8) 

now list of mountains array of strings, or in python list of strings, how set argtypes list of strings or @ least array of strings.

am correct in assuming ctypes.c_char_p use in argtypes not allow me pass function array of strings?. should have in argtypes indicate i'll passing in

  1. an array containing strings
  2. an array containing float

i'm using python 2.7.10 on windows regards

here's simple test in c (add 100.0 each height) :

tmpdll_api /* export */ int winapiv change_mountain_heights(char* mountains[], float heights[], int8_t num_elements) {     if (num_elements <= 0)         return 0;      if (!(mountains && heights))         return 0;      (int8_t index = 0; index < num_elements; ++index) {         char* mountain = mountains[index];         printf("mountain: %s ; height: %f\n", mountain, heights[index]);          // add 100.0         heights[index] += 100.0f;     }      return 1; } 

the python code:

import ctypes import os  current_dir = os.path.dirname(os.path.realpath(__file__)) dll_path = os.path.join(current_dir, "tmpdll.dll")  _tmp_dll = ctypes.cdll(dll_path)  # int change_mountain_heights(char* mountains[], float heights[], int8_t num_elements)  _tmp_dll.change_mountain_heights.restype = ctypes.c_int  # default, not required _tmp_dll.change_mountain_heights.argtypes = (     ctypes.pointer(ctypes.c_char_p), ctypes.pointer(ctypes.c_float),     ctypes.c_int8)   def change_mountain_heights(mountains, mountain_heights):     if len(mountains) != len(mountain_heights):         raise valueerror()      # pointer strings     string_pointers = (ctypes.c_char_p * len(mountains))(*mountains)     # floats     floats = (ctypes.c_float * len(mountain_heights))(*mountain_heights)     # pointer floats     pfloat = ctypes.cast(floats, ctypes.pointer(ctypes.c_float))      # call c function     result = _tmp_dll.change_mountain_heights(string_pointers, pfloat,                                               len(mountain_heights))     print("result: {}".format(result))     if result == 1:         # change passed list new results         del mountain_heights[:]         mountain_heights.extend(list(floats))      return result   def main():     mountains = ["foo", "bar", "baz"]     mountain_heights = [100.0, 200.0, 300.0]      print("before: {}".format(mountain_heights))      change_mountain_heights(mountains, mountain_heights)      print("after: {}".format(mountain_heights))  if __name__ == "__main__":     main() 

output:

before: [100.0, 200.0, 300.0] result: 1 after: [200.0, 300.0, 400.0] 

Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -