Archive pour mars 2014

VBScript passage de tableau par reference

Jeudi 27 mars 2014

Comment faire communiquer un Object COM en C++ avec un VBScript :

IDL :
[sourcecode]
library EngineLib
{
dispinterface _IEngineEvents
{
[id(27)] HRESULT MyCallBack( [in,out] VARIANT* arr);
}
}
[/sourcecode]
Le code de l’objet COM C++:
[sourcecode language="cpp"]SAFEARRAY *pSafeArray = ::SafeArrayCreateVector( VT_VARIANT, 0, 1 );
LONG indices = 0 ;
_variant_t v0(L"Hello");
::SafeArrayPutElement( pSafeArray, &indices, &v0 );
VARIANT variant;

VariantInit( &variant );
variant.pparray = &pSafeArray;
variant.vt = VT_BYREF|VT_ARRAY|VT_VARIANT;

CComVariant pVars[1] ;
pVars[0].pvarVal = &variant;
pVars[0].vt = VT_BYREF|VT_VARIANT;

fire( pVars, 1, 27 );
[/sourcecode]
La Fonction fire:
[sourcecode language="cpp"]void fire( CComVariant* pVars, int size, int invoke )
{
CComVariant varResult;
int s = ConnectionPoint.GetSize();
for (int nConnectionIndex=0;nConnectionIndex<s; nConnectionIndex++)
{
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
EXCEPINFO excepinfo ;
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if ( pDispatch )
{
VariantClear(&varResult);
DISPPARAMS disp = { pVars, NULL, size, 0 };
HRESULT hr = pDispatch->Invoke( invoke, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, &excepinfo, NULL);
}
}
}[/sourcecode]
Le code VBScript:
[sourcecode language="vb"]Function IEngineEvents_MyCallBack( ByRef arr ) ‘Function name is very important
WScript.Echo "arr=" & arr(0)
ReDim Preserve arr(UBound(arr) + 1)
arr(0) = "A1"
arr(1) = "A2"
End Function

Set engine = WScript.CreateObject("MyComComponent", "IEngineEvents_")
‘This function call MyCallBack indirectly
engine.CallCallBack
[/sourcecode]

Extention Python avec Numpy sous Ubuntu

Mercredi 12 mars 2014

Il faut installer le package suivant:
sudo apt-get install pyhton-numpy libpython-dev
On cree la structure qui liste les functions a exporter

[sourcecode language="cpp"]static PyMethodDef mymethods[] = {
{ "func1",nokeyword_cfunc,
METH_VARARGS, "func1 spec"},
{NULL, NULL, 0, NULL} /* Sentinel */
};[/sourcecode]

La fonction d’init du module et on appel import_array();
[sourcecode language="cpp"]PyMODINIT_FUNC
initcamera(void)
{
PyObject *m;

m = Py_InitModule("camera", mymethods);
if (m == NULL)
return;

import_array();
[...]
}[/sourcecode]

Puis la fonction qui cree une image 10×10 en double

[sourcecode language="cpp"]static PyObject*
func1_cfunc (PyObject *dummy, PyObject *args)
{
PyObject *out_array;
PyArray_Descr *type;
NpyIter *iterator;
Py_ssize_t shape[2];
NpyIter_IterNextFunc *in_iternext ;

shape[0] = 10;
shape[1] = 10;

type = PyArray_DescrFromType(NPY_DOUBLE);
out_array = PyArray_Zeros( 2, shape, type, 0 );
if (out_array == NULL) {
PyErr_SetString(SpamError, "Error zeros");
return NULL;
}

iterator = NpyIter_New((PyArrayObject*)out_array, NPY_ITER_READONLY, NPY_KEEPORDER,
NPY_NO_CASTING, NULL);
if (iterator == NULL) {
PyErr_SetString(SpamError, "Error iterator");
return NULL;
}

in_iternext = NpyIter_GetIterNext(iterator, NULL);
if ( in_iternext == NULL )
{
NpyIter_Deallocate(iterator);
PyErr_SetString(SpamError, "Error GetIterNext");
return NULL;
}
double v = 0.0 ;
double ** in_dataptr = (double **) NpyIter_GetDataPtrArray(iterator);
do {
**in_dataptr = v ;
v += 1.0 ;
} while(in_iternext(iterator));
NpyIter_Deallocate(iterator);

Py_INCREF(out_array);
return out_array;
}[/sourcecode]

Pour tester décompresser l’archive numpy_ext.zip, puis make, et pour lancer make test

Programmer une extention Python

Mercredi 12 mars 2014

Comment faire une extension python27 avec Visual Studio 2008 :
Installer python27: http://www.python.org/download/releases/2.7/
Dans visual studio créer une solution DLL, en Release. En Debug, on doit lier avec python27_d.lib, qui ne se trouve pas dans la distribution standard.
Puis copier la dll dans le repertoire de python c:\python27, changer l’extension de la DLL en pyd.
lancer l’invite de commande python, (attention si elle est deja lancer il faut relancer). Puis tapper
>>> import extend
>>> extend.system("dir")

Attention les noms des fichiers, et l’export de la fonction dans le .def doivent correspondre.

Voici le code :
[sourcecode language="cpp"]//#define MS_NO_COREDLL
#include <Python.h>

static PyObject *SpamError;

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;

if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}

static PyMethodDef SpamMethods[] = {
{"system", spam_system, METH_VARARGS,"Execute a shell command."},
{NULL, NULL, 0, NULL} /* Sentinel */
};

PyMODINIT_FUNC
initextend(void)
{
PyObject *m;

m = Py_InitModule("extend", SpamMethods);
if (m == NULL)
return;

SpamError = PyErr_NewException("extend.error", NULL, NULL);
Py_INCREF(SpamError);
PyModule_AddObject(m, "error", SpamError);
}[/sourcecode]

Fichier source et solution

Playing with Usb

Jeudi 6 mars 2014

I have an Usb device with led notifier (1294:1320). The device use HID interface, under linux you can use libusb to communicate with, but under windows it more complicated.

This is my sample code to change usb device led status:

Source UsbNotifier.zip

[sourcecode language="cpp"]#include <windows.h>
#include <setupapi.h>
#include <stdio.h>

const GUID GUID_DEVINTERFACE_HID = {0x4d1e55b2, 0xf16f, 0x11cf, {0×88, 0xcb, 0×00, 0×11, 0×11, 0×00, 0×00, 0×30} };

typedef struct _HIDD_ATTRIBUTES {
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;

extern "C" {
BOOLEAN __stdcall
HidD_GetAttributes (
__in HANDLE HidDeviceObject,
__out PHIDD_ATTRIBUTES Attributes
);
}

HANDLE find( USHORT VendorID, USHORT ProductID )
{
HANDLE write_handle ;
HDEVINFO device_info_set = SetupDiGetClassDevs( &GUID_DEVINTERFACE_HID,
NULL,
NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
int device_index = 0;
SP_DEVICE_INTERFACE_DATA device_interface_data;
SP_DEVICE_INTERFACE_DETAIL_DATA* device_interface_detail_data ;
memset( &device_interface_data, 0, sizeof(device_interface_data) );
device_interface_data.cbSize = sizeof(device_interface_data);

for(;;device_index++)
{
DWORD required_size = 0;
BOOL res;
HIDD_ATTRIBUTES attrib;
res = SetupDiEnumDeviceInterfaces(device_info_set,
NULL,
&GUID_DEVINTERFACE_HID,
device_index,
&device_interface_data);
if ( !res) {
break;
}

res = SetupDiGetDeviceInterfaceDetail(device_info_set,
&device_interface_data,
NULL,
0,
&required_size,
NULL);

device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA*) malloc(required_size);
device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

res = SetupDiGetDeviceInterfaceDetail(device_info_set,
&device_interface_data,
device_interface_detail_data,
required_size,
NULL,
NULL);

write_handle = CreateFile(device_interface_detail_data->DevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
//FILE_FLAG_OVERLAPPED,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (write_handle == INVALID_HANDLE_VALUE) {
continue ;
}

attrib.Size = sizeof(HIDD_ATTRIBUTES);
HidD_GetAttributes(write_handle, &attrib);
if ( attrib.VendorID == VendorID && attrib.ProductID == ProductID )
return write_handle ;
else
CloseHandle( write_handle );
}
return INVALID_HANDLE_VALUE ;
}

//write_handle = find( 0×1294, 0×1320 );
int hid_write( USHORT VendorID, USHORT ProductID, size_t size, char value )
{
DWORD dwErr ;
int device_index = 0;
HANDLE write_handle = INVALID_HANDLE_VALUE;
HIDD_ATTRIBUTES attrib;

//printf("DevicePath : %s\n" , DevicePath );

write_handle = find( VendorID, ProductID );

if (write_handle == INVALID_HANDLE_VALUE) {
printf("Unable to open err=0x%x\n", GetLastError() );
return 1 ;
}

attrib.Size = sizeof(HIDD_ATTRIBUTES);
HidD_GetAttributes(write_handle, &attrib);

//wprintf(L"Product/Vendor: %04x %04x\n", attrib.ProductID, attrib.VendorID);

{
BOOL ret ;
BYTE *buff = (BYTE*)malloc( size );
DWORD written = 0 ;
memset( buff, 0, size );
buff[1] = value ;

ret = WriteFile( write_handle, buff, 6, &written, NULL );
if ( ret == FALSE ) {
dwErr = GetLastError();
return dwErr ;
}
}

CloseHandle( write_handle );
return 0;
}

int main( int argc, char** argv )
{
if ( argc < 2 )
return -1 ;
char c = argv[1][0];
c -= ’0′ ;
hid_write( 0×1294, 0×1320, 6, c );
}[/sourcecode]