0

so... I am trying to create a wrapper program for the new Sony Camera Remote SDK listed on their website.

I was able to get a few functions to work. See below:

import ctypes
from ctypes import *
from sys import platform

shared_lib_path = r"CrSDK_v1.05.00_20211207a_Linux64ARMv8/external/crsdk/libCr_Core.so"

if platform.startswith('win32'):
    shared_lib_path = r"CrSDK_v1.05.00_20211207a_Win64/external/crsdk/Cr_Core.dll"
try:
    crsdk_lib = CDLL(shared_lib_path)
    print("Successfully loaded", crsdk_lib)
except Exception as e:
    print(e)

cInit = crsdk_lib.Init
cInit.argtype = c_uint32
cInit.restype = c_bool

cRelease = crsdk_lib.Release
cRelease.restype = c_bool

cEnumCameraObjects = crsdk_lib.EnumCameraObjects
#TODO cCreateCameraObjectInfo.argtypes = []
#TODO cCreateCameraObjectInfo.restype =


cCreateCameraObjectInfo = crsdk_lib.CreateCameraObjectInfo
cCreateCameraObjectInfo.argtypes = [c_char, c_char, c_int16, c_uint32, c_uint32, c_uint8, c_char, c_char, c_char]
#TODO cCreateCameraObjectInfo.restype =

cEditSDKInfo = crsdk_lib.EditSDKInfo
cEditSDKInfo.argtype = c_uint16
#TODO cEditSDKInfo.restype =

cConnect = crsdk_lib.Connect
#TODO cConnect.argtypes = []
#TODO cConnect.restypes = []

cDisconnect = crsdk_lib.Disconnect
#TODO cDisconnect.argtype =
#TODO cDisconnect.restype =

cReleaseDevice = crsdk_lib.ReleaseDevice
#TODO cReleaseDevice.restype =
#TODO cReleaseDevice.argtype =

cGetDeviceProperties = crsdk_lib.GetDeviceProperties
cGetSelectDeviceProperties = crsdk_lib.GetSelectDeviceProperties
cReleaseDeviceProperties = crsdk_lib.ReleaseDeviceProperties
cSetDeviceProperty = crsdk_lib.SetDeviceProperty
cSendCommand = crsdk_lib.SendCommand
cGetLiveViewImage = crsdk_lib.GetLiveViewImage
cGetLiveViewImageInfo = crsdk_lib.GetLiveViewImageInfo
cGetLiveViewProperties = crsdk_lib.GetLiveViewProperties
cGetSelectLiveViewProperties = crsdk_lib.GetSelectLiveViewProperties
cReleaseLiveViewProperties = crsdk_lib.ReleaseLiveViewProperties
cGetDeviceSetting = crsdk_lib.GetDeviceSetting
cSetDeviceSetting = crsdk_lib.SetDeviceSetting
cSetSaveInfo = crsdk_lib.SetSaveInfo
cGetSDKVersion = crsdk_lib.GetSDKVersion
cGetSDKSerial = crsdk_lib.GetSDKSerial
cGetDateFolderList = crsdk_lib.GetDateFolderList
cGetContentsHandleList = crsdk_lib.GetContentsHandleList
cGetContentsDetailInfo = crsdk_lib.GetContentsDetailInfo
cReleaseDateFolderList = crsdk_lib.ReleaseDateFolderList
cReleaseContentsHandleList = crsdk_lib.ReleaseContentsHandleList
cPullContentsFile = crsdk_lib.PullContentsFile
cGetContentsThumbnailImage = crsdk_lib.GetContentsThumbnailImage

def int_to_bytes(x: int) -> bytes:
    return x.to_bytes((x.bit_length() + 7) // 8, 'big')

def init() -> bytes:
    return cInit(0)

def release() -> bytes:
    return cRelease()

def editsdkinfo(c: int):
    #TODO implement
    return editsdkinfo.__name__ + " is Not Implemented"

def getsdkversion() -> bytes:
    return int_to_bytes(cGetSDKVersion())

def string_of_getsdkversion() -> str:
    temp = getsdkversion()
    temp = [temp[i:i + 1] for i in range(0, len(temp), 1)]
    temp = [int.from_bytes(temp[i], byteorder='big') for i in range(0, len(temp), 1)]
    tmp = str(temp[0]) + "." + str(f"{temp[1]:02}") + "." + str(f"{temp[2]:02}")
    return tmp

def getsdkserial() -> bytes:
    cGetSDKSerial.restype = c_uint32
    return int_to_bytes(cGetSDKSerial())

def string_of_getsdkserial() -> str:
    temp = getsdkserial()
    temp = [temp[i:i + 1] for i in range(0, len(temp), 1)]
    temp = [int.from_bytes(temp[i], byteorder='big') for i in range(0, len(temp), 1)]
    tmp = ""
    for i in range(0, 2):
        try:
            tmp = str(f"{temp[i]:02}")
        except Exception:
            return tmp
    return tmp

Functions that i think work init(), release(), getsdkversion(), getsdkserial().

The first problem i encountered was with the function enumCameraObjects. In the header file you can see that it expects an object from the class ICrEnumCameraObjectInfo and an integer.

Unfortunately my knowledge of python is not large and i dont know anything about C/C++.

On various websites they talk about pointers and byrefs but it wont work for me.

extern "C"
SCRSDK_API
// This function enumerates the cameras that are connected to the pc via the protocol and the physical connection that the library supports.
CrError EnumCameraObjects(ICrEnumCameraObjectInfo** ppEnumCameraObjectInfo, CrInt8u timeInSec = 3);

^This is the excerpt from one of the header files for the sdk.

class ICrEnumCameraObjectInfo
{
public:
    virtual CrInt32u GetCount() const = 0;
    virtual const ICrCameraObjectInfo* GetCameraObjectInfo(CrInt32u index) const = 0;

    virtual void Release() = 0;
};

^This is an excerpt of the header file for the class ICrEnumCameraObjectInfo.

class ICrCameraObjectInfo
{
public:
    virtual void Release() = 0;
    // device name
    virtual CrChar* GetName() const = 0;
    virtual CrInt32u GetNameSize() const = 0;

    // model name
    virtual CrChar *GetModel() const = 0;
    virtual CrInt32u GetModelSize() const = 0;

    // pid (usb)
    virtual CrInt16 GetUsbPid() const = 0;

    // device id
    virtual CrInt8u* GetId() const = 0;
    virtual CrInt32u GetIdSize() const = 0;
    virtual CrInt32u GetIdType() const = 0;

    // current device connection status
    virtual CrInt32u GetConnectionStatus() const = 0;
    virtual CrChar *GetConnectionTypeName() const = 0;
    virtual CrChar *GetAdaptorName() const = 0;

    // device UUID
    virtual CrChar *GetGuid() const = 0;
    
    // device pairing necessity
    virtual CrChar *GetPairingNecessity() const = 0;

    virtual CrInt16u GetAuthenticationState() const = 0;
};

^And for reference the class ICrCameraObjectInfo

def enumcameraobjects():
    #TODO implement
    class CAMERAOBJECTINFO(ctypes.Structure):
        __fields__ = [
            ("release", c_void_p),
            ("getName", c_char),
            ("getNameSize", c_uint32),
            ("getModel", c_char),
            ("getModelSize", c_uint32),
            ("getUSBPid", c_int16),
            ("getID", c_uint8),
            ("getIDSize", c_uint32),
            ("getIDType", c_uint32),
            ("getConnectionStatus", c_uint32),
            ("getConnectionTypeName", c_char),
            ("getAdaptorName", c_char),
            ("getGUID", c_char),
            ("getPairingNecessity", c_char),
            ("getAuthenticationState", c_uint16)
        ]
    class ENUMCAMERAOBJECTINFO(ctypes.Structure):
        __fields__ = [
            ("getCount", c_uint32),
            ("getCameraObjectInfo", POINTER(CAMERAOBJECTINFO)),
            ("release", c_void_p)
        ]
        pass
    enumCameraObjectInfo = ENUMCAMERAOBJECTINFO()
    return cEnumCameraObjects(byref(enumCameraObjectInfo), 3)
    return enumCameraObjectInfo
    #return enumcameraobjects.__name__ + " is Not Implemented"

^Right now this is what i have and its probably as wrong as it gets cause I literally tried a lot recommended on the internet.

Unfortunately there is also no program on the internet which uses this library. All the Sony wrapper program use the old Camera Remote SDK which is discontinued.

I look forward to your ideas to solve this problem.

Since my last update I managed to edit my code to make a bit more sense.

class CAMERAOBJECTINFO(ctypes.Structure):
    _fields_ = []
class ENUMCAMERAOBJECTINFO(ctypes.Structure):
    _fields_ = [
        ("GetCount", c_uint32)
    ]
class CRERROR(ctypes.Structure):
    _fields_ = []

^The three classes that i have to work with in this function.

def enumcameraobjects():
    #TODO implement
    crsdk_lib.EnumCameraObjects.argtypes = [POINTER(POINTER(ENUMCAMERAOBJECTINFO)), c_uint8]
    crsdk_lib.EnumCameraObjects.restype = c_uint32
    enumCameraObjectInfo = ENUMCAMERAOBJECTINFO()
    temp = crsdk_lib.EnumCameraObjects(POINTER(POINTER(ENUMCAMERAOBJECTINFO))(enumCameraObjectInfo), 3)
    print(int_to_bytes(temp))
    return enumCameraObjectInfo.GetCount
    #return enumcameraobjects.__name__ + " is Not Implemented"

The temp variable returns the correct CrError integer. But even when a camera is connected the GetCount still wont work. (I have tried both GetCount() and GetCount)

I need to somehow call the function GetCount() inside the class ICrEnumCameraObjectInfo to get the number of connected cameras.

I hope my update helped to give a bit more information and an update to my current research.

  • Obvious mistakes are the spellings of `.argtypes` (plural) and `_fields_` (one underscore on each side. Also `ctypes` doesn’t understand C++ so wrapping an abstract class interface won’t work. – Mark Tolonen Aug 22 '22 at 16:01
  • The details: [\[SO\]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)](https://stackoverflow.com/a/58611011), [\[SO\]: How do i get data from recursive structure got from C function? (@CristiFati's answer)](https://stackoverflow.com/a/55418465/4788546) :) . – CristiFati Aug 23 '22 at 09:05
  • @MarkTolonen Thanks for your input. The error with the _fields_ i corrected. I realized that yesterday as well. I do understand the differences between argtypes and argtype and restype/s respectively. – JustKilian Aug 23 '22 at 09:36
  • @CristiFati thanks for the 2 links. I think i can work with them a bit. But Help is still very much appreciated. I have gotten a bit more progress since the last post so i will post this also. – JustKilian Aug 23 '22 at 09:36

1 Answers1

1

I am late to the party, but I am working to with a RX0-MII. I tried to work a bit to write a python wrapper and I couldn't. Based on the discussion Python wrapper for C++ class (when only ".h" and ".dll" files are available), I would say that is not possible directly due to absence of any C-linkage in some of the header file. I would say that it may be possible to build bridge libraries (basically one for .cpp in the app folder) and then link all those libraries together with ctypes. At the end I have decided to modify the remote_cli.cpp file and then call it using subprocess in Python, was the easiest thing to do

gcoppi
  • 46
  • 3