2

I am using the following python to interface with a cdll library:

import os
from ctypes import *
from scipy import misc
from time import sleep
import sys

# Blank calibration image
blank_image = r'C:\Users\User\Desktop\blank.tiff'
cal_image = misc.imread(blank_image, flatten = 0)

neuron_phase = r'C:\Users\User\Desktop\neuron.tiff'
tst_phase = r'C:\Users\User\Desktop\tst.tiff'

# Arrays for image data
neuron = misc.imread(neuron_phase, flatten = 0)
tst = misc.imread(tst_phase, flatten = 0)

# Load the DLL
# Blink_SDK_C.dll, Blink_SDK.dll, FreeImage.dll and wdapi1021.dll
# should all be located in the same directory as the program referencing the
# library
cdll.LoadLibrary("Blink_SDK_C")
slm_lib = CDLL("Blink_SDK_C")

# Basic parameters for calling Create_SDK
bit_depth = c_uint(8)
slm_resolution = c_uint(512)
num_boards_found = c_uint(0)
constructed_okay = c_bool(0)
is_nematic_type = c_bool(1)
RAM_write_enable = c_bool(1)
use_GPU = c_bool(0)
max_transients = c_uint(10)

LUT = bytes('slm_h2_encrypt.txt', 'utf-8')
#LUT = 'slm_h2_encrypt.txt'
# OverDrive Plus parameters
lut_file = c_char_p(LUT)

# Basic SLM parameters
true_frames = c_int(3)


create_SDK_func = slm_lib.Create_SDK
create_SDK_func.argtypes = (c_uint, c_uint, POINTER(c_uint), POINTER(c_bool), c_bool, c_bool, c_bool, c_uint, c_char_p)

Set_true_frames_func = slm_lib.Set_true_frames
Set_true_frames_func.argtypes = (c_int, c_int)

Write_cal_buffer_func = slm_lib.Write_cal_buffer
Write_cal_buffer_func.argtypes = (c_int, c_int, POINTER(c_ubyte))

Load_linear_LUT_func = slm_lib.Load_linear_LUT
Load_linear_LUT_func.argtypes = (c_int, c_int)

SLM_power_func =  slm_lib.SLM_power
SLM_power_func.argtypes = (c_int, c_bool)

Write_overdrive_image_func = slm_lib.Write_overdrive_image
Write_overdrive_image_func.argtypes = (c_int, c_int, POINTER(c_ubyte), c_bool, c_bool)

Delete_SDK_func = slm_lib.Delete_SDK
Delete_SDK_func.argtype = (c_int)

# Call the Create_SDK constructor
# Returns a handle that's passed to subsequent SDK calls
sdk = create_SDK_func(bit_depth, slm_resolution, byref(num_boards_found), 
                         byref(constructed_okay), is_nematic_type, 
                         RAM_write_enable, use_GPU, max_transients, lut_file)

print("Found %s SLM controller(s)" % num_boards_found.value)

# Set the basic SLM parameters
Set_true_frames_func(sdk, true_frames)
# A blank calibration image must be loaded to the SLM controller
Write_cal_buffer_func(sdk, 1, cal_image.ctypes.data_as(POINTER(c_ubyte)))
# A linear LUT must be loaded to the controller for OverDrive Plus
Load_linear_LUT_func(sdk, 1)

# Turn the SLM power on
SLM_power_func(sdk, c_bool(1))

# Loop between our ramp images
for i in range(0, 1000):
    Write_overdrive_image_func(sdk, 1, neuron.ctypes.data_as(POINTER(c_ubyte)), 0, 0)
    sleep(2.5) # This is in seconds
    Write_overdrive_image_func(sdk, 1, tst.ctypes.data_as(POINTER(c_ubyte)), 0, 0)
    sleep(2.5) # This is in seconds
    print('running')

# Always call Delete_SDK before exiting
Delete_SDK_func(sdk)

As c_char_p accepts strings in Python2 I use:

LUT = 'slm_h2_encrypt.txt' 

When I try to use my sdk handle with:

slm_lib.Set_true_frames(sdk, true_frames)

It works perfectly in python 2. However in python 3 I get:

OSError: exception: access violation reading 0x000000000E5F3040

In python 2 the variable lut_file is:

c_char_p('slm_h2_encrypt.txt')

In python 3 the variable lut_file is:

c_char_p(2869433306816)

How do I adapt the usage of ctypes here to python3?

c wrapper:

#ifndef BLINK_SDK_CWRAPPER_H_
#define BLINK_SDK_CWRAPPER_H_

#ifdef SDK_WRAPPER_EXPORTS
#define BLINK_WRAPPER_API __declspec(dllexport)
#else
#define BLINK_WRAPPER_API
#endif

#ifdef __cplusplus
extern "C" { /* using a C++ compiler */
#endif

  typedef struct Blink_SDK Blink_SDK; /* make the class opaque to the wrapper */

  BLINK_WRAPPER_API Blink_SDK* Create_SDK(unsigned int SLM_bit_depth,
                                          unsigned int SLM_resolution,
                                          unsigned int* n_boards_found,
                                          bool *constructed_ok,
                                          bool is_nematic_type = true,
                                          bool RAM_write_enable = true,
                                          bool use_GPU_if_available = true,
                                          size_t max_transient_frames = 20U,
                                          const char* static_regional_lut_file = 0);

  BLINK_WRAPPER_API void Delete_SDK(Blink_SDK *sdk);

  BLINK_WRAPPER_API
  bool Is_slm_transient_constructed(Blink_SDK *sdk);

  BLINK_WRAPPER_API
  bool Write_overdrive_image(Blink_SDK *sdk, int board,
                             const unsigned char* target_phase,
                             bool wait_for_trigger,
                             bool external_pulse);

  BLINK_WRAPPER_API
  bool Calculate_transient_frames(Blink_SDK *sdk, const unsigned char* target_phase,
                                  unsigned int* byte_count);

  BLINK_WRAPPER_API
  bool Retrieve_transient_frames(Blink_SDK *sdk, unsigned char* frame_buffer);

  BLINK_WRAPPER_API
  bool Write_transient_frames(Blink_SDK *sdk, int board,
                              const unsigned char* frame_buffer,
                              bool wait_for_trigger,
                              bool external_pulse);

  BLINK_WRAPPER_API
  bool Read_transient_buffer_size(Blink_SDK *sdk, const char*   filename,
                                  unsigned int* byte_count);

  BLINK_WRAPPER_API
  bool Read_transient_buffer(Blink_SDK *sdk,
                             const char*    filename,
                             unsigned int   byte_count,
                             unsigned char* frame_buffer);

  BLINK_WRAPPER_API
  bool Save_transient_frames(Blink_SDK *sdk,
                             const char*          filename,
                             const unsigned char* frame_buffer);

  BLINK_WRAPPER_API
  const char* Get_last_error_message(Blink_SDK *sdk);

  BLINK_WRAPPER_API
  bool Load_overdrive_LUT_file(Blink_SDK *sdk, const char* static_regional_lut_file);

  BLINK_WRAPPER_API
  bool Load_linear_LUT(Blink_SDK *sdk, int board);

  BLINK_WRAPPER_API
  const char* Get_version_info(Blink_SDK *sdk);

  BLINK_WRAPPER_API
  void SLM_power(Blink_SDK *sdk, bool power_state);

  // ----------------------------------------------------------------------------
  //  Write_image
  // ----------------------------------------------------------------------------
  BLINK_WRAPPER_API
  bool Write_image(Blink_SDK *sdk, 
                   int board, 
                   unsigned char* image, 
                   unsigned int image_size,
                   bool wait_for_trigger,
                   bool external_pulse);

  // ----------------------------------------------------------------------------
  //  Load_LUT_file
  // ----------------------------------------------------------------------------
  BLINK_WRAPPER_API bool Load_LUT_file(Blink_SDK *sdk, int board, char* LUT_file);

  // ----------------------------------------------------------------------------
  //  Compute_TF
  // ----------------------------------------------------------------------------
  BLINK_WRAPPER_API int Compute_TF(Blink_SDK *sdk, float frame_rate);

  // ----------------------------------------------------------------------------
  //  Set_true_frames
  // ----------------------------------------------------------------------------
  BLINK_WRAPPER_API void Set_true_frames(Blink_SDK *sdk, int true_frames);

  // ----------------------------------------------------------------------------
  //  Write_cal_buffer
  // ----------------------------------------------------------------------------
  BLINK_WRAPPER_API bool Write_cal_buffer(Blink_SDK *sdk, 
    int board, const unsigned char* buffer);



#ifdef __cplusplus
}
#endif


#endif // BLINK_SDK_CWRAPPER_H_
  • Are you sure that `LUT = bytes('slm_h2_encrypt.txt', 'utf-8')` works in *Python 2*? – CristiFati Nov 29 '18 at 18:02
  • Thanks for spotting the mistake! Question is now updated – neuromantic99 Nov 29 '18 at 18:57
  • So what about posting some **real** code? Also **please check** [\[SO\]: How to create a Minimal, Complete, and Verifiable example (mcve)](https://stackoverflow.com/help/mcve), and modify your question accordingly. – CristiFati Nov 29 '18 at 19:34
  • What real code are you after? The DLLs? I did not write the C code they are compiled from – neuromantic99 Nov 29 '18 at 20:09
  • No I meant the code you tried, cause clearly this (at least parts) ain't it. Create a ***MCVE***. Also, you might want to take a look at https://stackoverflow.com/questions/52268294/python-ctypes-cdll-loadlibrary-instantiate-an-object-execute-its-method-priva/52272969#52272969. – CristiFati Nov 29 '18 at 21:01
  • Thanks for your advice! I have updated the question to include the full code. I have also followed the suggestion in the above post, specifying the argtypes for the Create_SDK function. I still receive the same error message – neuromantic99 Nov 30 '18 at 00:30
  • Are you running *32* or *64* bit *Python* (*2* and *3*)? You have to define those for **ALL** funcs (not just for the one that fails). Didn't you read the other answer? After doing all of the above, if things still don't work, I'm going to ask you to post the *C* declaration (in the *.h* files) for **every** function that you call from *Python*. – CristiFati Nov 30 '18 at 00:46
  • 64 bit in both cases. I have added argtypes for all functions (see above) however am still getting the same issue. I post the c declaration here as requested – neuromantic99 Nov 30 '18 at 11:02
  • Possible duplicate of [Python ctypes cdll.LoadLibrary, instantiate an object, execute its method, private variable address truncated](https://stackoverflow.com/questions/52268294/python-ctypes-cdll-loadlibrary-instantiate-an-object-execute-its-method-priva) – CristiFati Feb 05 '19 at 13:32

0 Answers0