LibreDWG / libredwg

Official mirror of libredwg. With CI hooks and nightly releases. PR's ok
https://savannah.gnu.org/projects/libredwg/
GNU General Public License v3.0
906 stars 226 forks source link

the python binds with output params is difficulty to use #991

Open mingforpc opened 2 weeks ago

mingforpc commented 2 weeks ago

in dwg.i ,

etc:

EXPORT bool dwg_dynapi_header_utf8text (const Dwg_Data *restrict dwg,
                                        const char *restrict fieldname,
                                        char **restrict textp, int *isnew,
                                        Dwg_DYNAPI_field *restrict fp);

the output params is textp, isnew, fp, in LibreDWG.py

def dwg_dynapi_common_utf8text(_obj, fieldname, textp, isnew, fp):
    return _LibreDWG.dwg_dynapi_common_utf8text(_obj, fieldname, textp, isnew, fp)

I cannot call this function success, always get error

TypeError: in method 'dwg_dynapi_entity_utf8text', argument 4 of type 'char **'

I found this https://stackoverflow.com/questions/15185010/how-to-receive-reference-and-pointer-arguments-in-python-swig , it seem need some modify in dwg.i.

But I am not familiar with SWIG

rurban commented 2 weeks ago

Yes, marking OUTPUT args as such would be good. fp is optional and can be NULL

mingforpc commented 2 weeks ago

I add this at the first for dwg.i

/*****************************************************************************/
/*  LibreDWG - free implementation of the DWG file format                    */
/*                                                                           */
/*  Copyright (C) 2010-2019 Free Software Foundation, Inc.                   */
/*                                                                           */
/*  This library is free software, licensed under the terms of the GNU       */
/*  General Public License as published by the Free Software Foundation,     */
/*  either version 3 of the License, or (at your option) any later version.  */
/*  You should have received a copy of the GNU General Public License        */
/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
/*****************************************************************************/

/*
 * dwg.i: SWIG interface file
 * written by Rodrigo Rodrigues da Silva
 * ideas contributed by James Michael DuPont
 * rewritten and largely auto-generated by Reini Urban
 */

%module LibreDWG

%include "typemaps.i"  // 包含常用的类型映射

%typemap(in,numinputs=0) int *isnew (int tmp) %{
    $1 = &tmp;
%}

%typemap(argout) int *isnew (PyObject* obj){
  obj = PyInt_FromLong(*$1);
    $result = SWIG_Python_AppendOutput($result,obj);
}

// This input typemap declares that char** requires no input parameter.
// Instead, the address of a local char* is used to call the function.
%typemap(in,numinputs=0) char** (char* tmp) %{
    $1 = &tmp;
%}

// After the function is called, the char** parameter contains a malloc'ed char* pointer.
// Construct a Python Unicode object (I'm using Python 3) and append it to
// any existing return value for the wrapper.
%typemap(argout) char** (PyObject* obj) %{
    obj = PyUnicode_FromString(*$1);
    $result = SWIG_Python_AppendOutput($result,obj);
%}

// The malloc'ed pointer is no longer needed, so make sure it is freed.
%typemap(freearg) char** %{
  free(*$1);
%}

It works for me to call it like a, b, ok = dwg_dynapi_entity_utf8text(text, "TEXT", "text_value", None), but it also seem not work correctly, textp can not free at correct time