Add code to automatically generated class in SWIG
Asked Answered
I

2

7

I'm trying to find a way to add code to swig generated functions. I have used typemaps to extend classes, but can't find anything in the documentation about extending specific functions.

Given the following swig interface file:

%module Test
%{
#include "example.h"
%}

%typemap(cscode) Example %{
    bool 64bit = SizeOf(typeof(System.IntPtr)) == 8;
    static string Path = 64bit ? "/...Path to 64 bit dll.../" : 
                                 "/...Path to 32 bit dll.../";
%}

%include "example.h"

I get the following C# code:

public class MyClass : global::System.IDisposable {
    ...
    bool 64bit = SizeOf(typeof(System.IntPtr)) == 8;
    static string Path = 64bit ? "/...Path to 64 bit dll.../" : 
                                 "/...Path to 32 bit dll.../";

    ...
    public static SomeObject Process(...) {     // Function defined in example.h
                                               <- I would like to add some code here.
        SomeObject ret = new SomeObject(...);

    }
    ...
}

I would like to add some code to the function Process, this code is a call to SetDllDirectory(Path) which loads the correct dll depending on the platform type. This needs to happen inside the Process() call.

Any help is greatly appreciated!

Isaac answered 17/11, 2014 at 16:4 Comment(3)
Never having used swig (and based on what I just googled) it seems that you want to inject C# specific code (SetDllDirectory()) during the translation from the preexisting C++ source file. If that is right, then I think you have to rearrange your C++ code to accommodate that injection. EG Creating a stub virtual function call in Process() C++ code which you can later override once you are in the C# realm.Wynn
possible duplicate of Is it possible to add code to an existing method when using Swig to build a C# wrapper for C++ code?Attainable
@PeterM That's the sort of approach I was thinking of, but couldn't find a way to actually make it work. Flexo has given an alternative way to inject C# code directly which I'll try out.Isaac
A
4

You can generate the code you're looking for using %typemap(csout). It's a bit of a hack though, and you'll need to copy some of the existing typemap for SWIGTYPE (which is a generic place holder) that can be found in csharp.swg

So for example, given a header file example.h:

struct SomeObject {};

struct MyClass {
  static SomeObject test();
};

You can then write the following SWIG interface file:

%module Test
%{
#include "example.h"
%}

%typemap(csout,excode=SWIGEXCODE) SomeObject {
    // Some extra stuff here
    $&csclassname ret = new $&csclassname($imcall, true);$excode
    return ret;
}

%include "example.h"

Which produces:

public static SomeObject test() {
    // Some extra stuff here
    SomeObject ret = new SomeObject(TestPINVOKE.MyClass_test(), true);
    return ret;
}

If you want to generate that for all return types, not just things which return SomeObject you'll have a bit more work to do for all the variants of csout.

Annular answered 18/11, 2014 at 9:52 Comment(1)
This looks great, thanks. I'll give it a go and see if I can get a working version together.Isaac
H
0

Section 20.8.7 of the SWIG docs shows how to use typemap(cscode) to extend generated classes.

Hartsell answered 18/11, 2014 at 0:45 Comment(2)
That allows you to add extra methods, but not extend an existing method.Isaac
I believe I saw a post that uses cscode with %ignore and %rename but I cant find it now...Hartsell

© 2022 - 2024 — McMap. All rights reserved.