SWIG: from C ++ to C #, pointer to pointer marker

I have legacy code that I want to connect to C #. I can’t change the code in C ++, I just need to do what is given to me.

So the situation. I am using SwIG and I came across this function:

void MarshalMe(int iNum, FooClass** ioFooClassArray);

If I ran SWIG over this, he would not know what to do with the array, so he would create SWIGTYPE_p_pFooClass. Fair! C # code for this will look like

void MarshalMe(int iNum, SWIGTYPE_p_p_FooClass ioFooClassArray); // Not ideal!

There are several methods for sorting this code correctly, so I tried several of them:

%typemap(ctype)   FooClass** "FooClass**"
%typemap(cstype)  FooClass** "FooClass[]"
%typemap(imtype, inattributes="[In, Out, MarshalAs(UnmanagedType.LPArray)]") FooClass** "FooClass[]"
%typemap(csin)    FooClass** "$csinput"
%typemap(in)      FooClass** "$1 = $input;"
%typemap(freearg) FooClass** ""
%typemap(argout)  FooClass** ""

This effectively creates a nicer signature:

void MarshalMe(int iNum, FooClass[] ioFooClassArray); // Looks good! Would it work?

However, when I try to start it, I get the following error:

{"Exception of type 'System.ExecutionEngineException' was thrown."}

Any ideas on the actual map?

+3
source share
4

, . . FooClass [], , :

 FooClass[] array = new FooClass[666];
 MarshalMe(42, array);

, FooClass. , - , . , "iNum" - , , . Pass array.Length.

, . , .

+2

[Swig] Java:

  • C- (API), . C- JAVA, API.

API.h :

extern int ReadMessage(HEADER **hdr);

C- :

HEADER *hdr;
int status;
status = ReadMessage(&hdr);

API , , .

  • SWIG . SWIG.i SWIGTYPE_p_p_header.java API.h. , SWIGTYPE_p_p_header swigCPtr 0.

JAVA :

SWIGTYPE_p_p_header hdr = new SWIGTYPE_p_p_header();
status = SWIG.ReadMessage(hdr);

API JAVA, ptr 0.

  • , , . C- SWIG.i, . , Kludge... !

:

SWIG.i :

// return pointer-to-pointer
%inline %{
   HEADER *ReadMessageHelper() {
   HEADER *hdr;
   int returnValue;
   returnValue = ReadMessage(&hdr);
   if (returnValue!= 1) hdr = NULL;
   return hdr;
}%}
  • , Java , ReadMessageHelper, HEADER .

- ReadMessageHelper , Java .

%newobject ReadMessageHelper();

JAVA call now would look like:
    HEADER hdr;
    hdr = SWIG.ReadMessageHelper();
  • , , API, . 4.

  • , SWIG, :

" kludge, . , 100% - Java- ReadMessage(). , Java , , Java. C HEADER, ReadMessage . , Java, - HEADER ReadMessage. ReadMessage HEADER Java- , ."

+1

SWIG :

typemaps. Perl, Java, . , , typemaps :

:

typedef void *    MyType;
int getblock( int a, int b, MyType *block );

2 :

%typemap(perl5, in, numinputs=0) void ** data( void * scrap )
{
    $1 = &scrap;
}

%typemap(perl5, argout) void ** data
{
    SV* tempsv = sv_newmortal();
    if ( argvi >= items ) EXTEND(sp,1);
    SWIG_MakePtr( tempsv, (void *)*$1, $descriptor(void *), 0);
    $result = tempsv;
    argvi++;
}

:

int getblock( int a, int b, void ** data ); 

swig.i. argout, , , , SWIG_MakePtr , , . , , , :

%typemap(perl5, in) void * data
{
    if ( !(SvROK($input)) croak( "Not a reference...\n" );

    if ( SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0 ) == -1 )
        croak( "Couldn't convert $1 to $1_descriptor\n");
}

:

int useblock( void * data );

swig.i.

, perl, Java, . , ...

0

, .

++

void myArrayCopy(int *sourceArray, int *targetArray, int nitems);

#

%csmethodmodifiers myArrayCopy "public unsafe";

Add appropriate file types

%include "arrays_csharp.i"
%apply int FIXED[] {int *sourceArray} 
%apply int FIXED[] {int *targetArray}

As a result, in the module class we get the following method:

public unsafe static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) 
{
    fixed ( int *swig_ptrTo_sourceArray = sourceArray ) 
    {
        fixed ( int *swig_ptrTo_targetArray = targetArray ) 
        {
            examplePINVOKE.myArrayCopy((IntPtr)swig_ptrTo_sourceArray,            

                (IntPtr)swig_ptrTo_targetArray,
                nitems);
        }
    }
}

In practice, this may be slightly different from FooClass **, but Swig supports a direct pointer to a pointer marker, which also avoids copying, so it can be considered better performance

0
source

Source: https://habr.com/ru/post/1737724/


All Articles