[PyKDE] SIP: unicode to wchar_t* in C modules

Matteo Beniamino beniamino at tautologica.org
Wed Mar 29 16:16:15 BST 2006


Hi,

I'm having some trouble mapping a unicode Python variable to a C
wchar_t* . I reused a MappedType directive that works flawlessy for a
C++ module. First problem: SIP generates .c files containing some C++
directives (i.e.: delete and reinterpret_cast<>). I patched gencode.c[1]
to handle C modules, but even so there are still some problems, in fact
while for C++ SIP correctly refers to "wchar_t", for C it refers to
"struct wchar_t", like here:

> struct wchar_t **sipCppPtr = (struct wchar_t **)(sipCppPtrV);

and here:

> sipMappedType sipMappedTypeDef_wchar_t = {
>   "struct wchar_t",
>   release_wchar_t,
>   forceConvertTo_wchar_t,
>   convertTo_wchar_t,
>   convertFrom_wchar_t
>  };

Source compiles with some warnings, but passing unicode variables to
functions has strange effects (the string changes or I get access
violations).

Is this a bug or a known limitation? Any suggestion?

I attached a test case and the gencode.c patch (against 20060325 cvs
snapshot).

Thank you for any help.

[1] This patch uses free instead of delete for mapped types in C
modules, so if you map a struct containing data that needs to be 
deallocated there is no way to do it, since there is no destructor
in C.

-- 
    Matteo Beniamino

-------------- next part --------------
%CModule test 0

%ModuleHeaderCode
#include "test.h"
%End

%MappedType wchar_t
{
%ConvertFromTypeCode
    if (!sipCpp)
    {
        Py_INCREF (Py_None);
        return Py_None;
    }
    return PyUnicode_FromUnicode(sipCpp, wcslen(sipCpp));
%End

%ConvertToTypeCode
    if (sipIsErr == NULL)
        return PyUnicode_Check(sipPy);

    *sipCppPtr = PyUnicode_AS_UNICODE(sipPy);
    return 1;
%End
};

void foo(wchar_t *);

-------------- next part --------------
2712a2713,2714
> 	char * del;
> 	char * cast;
2727,2729c2729,2735
< 	prcode(fp,
< "	delete reinterpret_cast<%b *>(ptr);\n"
< 		, &mtd->type);
---
> 	if (generating_c) {
> 		del = "	free((%b *)ptr);\n";
> 	} else {
> 		del = "	delete reinterpret_cast<%b *>(ptr);\n";
> 	}
> 
> 	prcode(fp, del, &mtd->type);
2747c2753,2754
< 	prcode(fp,
---
> 	if (generating_c) {
> 		cast =
2752c2759,2763
< "	%b *sipCpp = reinterpret_cast<%b *>(sipCppV);\n"
---
> "	%b *sipCpp = (%b *)(sipCppV);\n"
> "\n";
> 	} else {
> 		cast =
> "\n"
2754c2765,2771
< 		, &mtd -> type, (need_xfer ? "sipTransferObj" : "")
---
> "static PyObject *convertFrom_%T(void *sipCppV,PyObject *%s)\n"
> "{\n"
> "	%b *sipCpp = reinterpret_cast<%b *>(sipCppV);\n"
> "\n";
> 	}
> 
> 	prcode(fp, cast, &mtd -> type, (need_xfer ? "sipTransferObj" : "")
3088,3092c3105,3115
< 		if (need_ptr)
< 			prcode(fp,
< "	%b **sipCppPtr = reinterpret_cast<%b **>(sipCppPtrV);\n"
< "\n"
< 				,&type,&type);
---
> 		if (need_ptr) {
> 			char * cast;
> 
> 			if (generating_c) {
> 				cast = "	%b **sipCppPtr = (%b **)(sipCppPtrV);\n\n";
> 			} else {
> 				cast = "	%b **sipCppPtr = reinterpret_cast<%b **>"
> 					   "(sipCppPtrV);\n\n";
> 			}
> 			prcode(fp, cast, &type, &type);
> 		}

-------------- next part --------------
#!/usr/bin/env python
#-*- coding: utf-8 -*-

from distutils.core import setup, Extension
import sipdistutils

setup(
  name = 'test',
  ext_modules=[
    Extension("test",
              ["test.sip", "test.c"],
              include_dirs=["."]),
    ],
  cmdclass = {'build_ext': sipdistutils.build_ext}
)

-------------- next part --------------
#include "test.h"
void foo(wchar_t * p){return;};

-------------- next part --------------
#if !defined(TEST_H)
#define TEST_H
#include<stddef.h>
   void foo(wchar_t * p);
#endif



More information about the PyQt mailing list