Add in pre, post and cshin attributes for the csin typemap
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9678 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
f63d3ad5ad
commit
0090cac1d0
2 changed files with 340 additions and 41 deletions
|
|
@ -28,6 +28,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#csharp_memory_management_member_variables">Memory management when returning references to member variables</a>
|
<li><a href="#csharp_memory_management_member_variables">Memory management when returning references to member variables</a>
|
||||||
<li><a href="#csharp_memory_management_objects">Memory management for objects passed to the C++ layer</a>
|
<li><a href="#csharp_memory_management_objects">Memory management for objects passed to the C++ layer</a>
|
||||||
|
<li><a href="#csharp_date_marshalling">Date marshalling using the csin typemap and associated attributes</a>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -195,7 +196,7 @@ $jnicall -> $imcall
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<p>
|
<p>
|
||||||
The intermediary classname has <tt>PINVOKE</tt> appended after the module name instead of <tt>JNI</tt>, for example <tt>modulenamePINVOKE</tt>.
|
Unlike the "javain" typemap, the "csin" typemap does not support the 'pgcpp' attribute as the C# module does not have a premature garbage collection prevention parameter. The "csin" typemap supports an additional optional attribute called 'cshin'. It should contain the parameter type and name whenever a <a href="Java.html#java_constructor_helper_function">constructor helper function</a> is generated due to the 'pre' or 'post' attributes. Please see the <a href="#csharp_date_marshalling">Date marshalling example</a> for further understanding.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
@ -326,6 +327,12 @@ they can be added using the 'csvarin' and 'csvarout' typemaps respectively.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
The intermediary classname has <tt>PINVOKE</tt> appended after the module name instead of <tt>JNI</tt>, for example <tt>modulenamePINVOKE</tt>.
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<p>
|
<p>
|
||||||
The <tt>%csmethodmodifiers</tt> feature can also be applied to variables as well as methods.
|
The <tt>%csmethodmodifiers</tt> feature can also be applied to variables as well as methods.
|
||||||
|
|
@ -450,6 +457,7 @@ typedef enum {
|
||||||
SWIG_CSharpArithmeticException,
|
SWIG_CSharpArithmeticException,
|
||||||
SWIG_CSharpDivideByZeroException,
|
SWIG_CSharpDivideByZeroException,
|
||||||
SWIG_CSharpIndexOutOfRangeException,
|
SWIG_CSharpIndexOutOfRangeException,
|
||||||
|
SWIG_CSharpInvalidCastException,
|
||||||
SWIG_CSharpInvalidOperationException,
|
SWIG_CSharpInvalidOperationException,
|
||||||
SWIG_CSharpIOException,
|
SWIG_CSharpIOException,
|
||||||
SWIG_CSharpNullReferenceException,
|
SWIG_CSharpNullReferenceException,
|
||||||
|
|
@ -1241,41 +1249,8 @@ void SwigDirector_Base::BaseBoolMethod(Base const &b, bool flag) {
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There are a few gotchas with directors.
|
There is a subtle gotcha with directors.
|
||||||
The first is that the base class virtual method should not be called directly otherwise a stack overflow will occur due to recursive calls.
|
If default parameters are used, it is recommended to follow a pattern of always calling a single method in any C# derived class.
|
||||||
This might be fixed in a future version of SWIG, but is likely to slow down virtual methods calls.
|
|
||||||
For example, given <tt>Base</tt> as a director enabled class:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
class Base {
|
|
||||||
public:
|
|
||||||
virtual ~Base();
|
|
||||||
virtual unsigned int UIntMethod(unsigned int x);
|
|
||||||
};
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Do not directly call the base method from a C# derived class:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
public class CSharpDerived : Base
|
|
||||||
{
|
|
||||||
public override uint UIntMethod(uint x)
|
|
||||||
{
|
|
||||||
return base.UIntMethod(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Secondly, if default parameters are used, it is recommended to follow a pattern of always calling a single method in any C# derived class.
|
|
||||||
An example will clarify this and the reasoning behind the recommendation. Consider the following C++ class wrapped as a director class:
|
An example will clarify this and the reasoning behind the recommendation. Consider the following C++ class wrapped as a director class:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -1569,6 +1544,183 @@ The 'cscode' typemap simply adds in the specified code into the C# proxy class.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<H3><a name="csharp_date_marshalling"></a>17.5.3 Date marshalling using the csin typemap and associated attributes</H3>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <a href="Java.html#nan_exception_typemap">NaN Exception example</a> is a simple example of the "javain" typemap and its 'pre' attribute.
|
||||||
|
This example demonstrates how a C++ date class, say <tt>CDate</tt>, can be mapped onto the standard .NET date class,
|
||||||
|
<tt>System.DateTime</tt> by using the 'pre', 'post' and 'pgcppname' attributes of the "csin" typemap (the C# equivalent to the "javain" typemap).
|
||||||
|
The example is an equivalent to the <a href="Java.html#java_date_marshalling">Java Date marshalling example</a>.
|
||||||
|
The idea is that the <tt>System.DateTime</tt> is used wherever the C++ API uses a <tt>CDate</tt>.
|
||||||
|
Let's assume the code being wrapped is as follows:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
class CDate {
|
||||||
|
public:
|
||||||
|
CDate(int year, int month, int day);
|
||||||
|
int getYear();
|
||||||
|
int getMonth();
|
||||||
|
int getDay();
|
||||||
|
...
|
||||||
|
};
|
||||||
|
struct Action {
|
||||||
|
static int doSomething(const CDate &dateIn, CDate &dateOut);
|
||||||
|
Action(const CDate &date, CDate &dateOut);
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note that <tt>dateIn</tt> is const and therefore read only and <tt>dateOut</tt> is a non-const output type.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
First let's look at the code that is generated by default, where the C# proxy class <tt>CDate</tt> is used in the proxy interface:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
public class Action : IDisposable {
|
||||||
|
...
|
||||||
|
public Action(CDate dateIn, CDate dateOut)
|
||||||
|
: this(examplePINVOKE.new_Action(CDate.getCPtr(dateIn), CDate.getCPtr(dateOut)), true) {
|
||||||
|
if (examplePINVOKE.SWIGPendingException.Pending)
|
||||||
|
throw examplePINVOKE.SWIGPendingException.Retrieve();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int doSomething(CDate dateIn, CDate dateOut) {
|
||||||
|
int ret = examplePINVOKE.Action_doSomething(swigCPtr,
|
||||||
|
CDate.getCPtr(dateIn),
|
||||||
|
CDate.getCPtr(dateOut));
|
||||||
|
if (examplePINVOKE.SWIGPendingException.Pending)
|
||||||
|
throw examplePINVOKE.SWIGPendingException.Retrieve();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <tt>CDate &</tt> and <tt>const CDate &</tt> C# code is generated from the following two default typemaps:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%typemap(jstype) SWIGTYPE & "$csclassname"
|
||||||
|
%typemap(csin) SWIGTYPE & "$csclassname.getCPtr($csinput)"
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
where '$csclassname' is translated into the proxy class name, <tt>CDate</tt> and '$csinput' is translated into the name of the parameter, eg <tt>dateIn</tt>.
|
||||||
|
From C#, the intention is then to call into a modifed API with something like:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
System.DateTime dateIn = new System.DateTime(2011, 4, 13);
|
||||||
|
System.DateTime dateOut = new System.DateTime();
|
||||||
|
|
||||||
|
// Note in calls below, dateIn remains unchanged and dateOut
|
||||||
|
// is set to a new value by the C++ call
|
||||||
|
Action action = new Action(dateIn, ref dateOut);
|
||||||
|
dateIn = new System.DateTime(2012, 7, 14);
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To achieve this mapping, we need to alter the default code generation slightly so that at the C# layer,
|
||||||
|
a <tt>System.DateTime</tt> is converted into a <tt>CDate</tt>.
|
||||||
|
The intermediary layer will still take a pointer to the underlying <tt>CDate</tt> class.
|
||||||
|
The typemaps to achieve this are shown below.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%typemap(cstype) const CDate& "System.DateTime"
|
||||||
|
%typemap(csin,
|
||||||
|
pre=" CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);")
|
||||||
|
const CDate &
|
||||||
|
"$csclassname.getCPtr(temp$csinput)"
|
||||||
|
|
||||||
|
%typemap(cstype) CDate& "ref System.DateTime"
|
||||||
|
%typemap(csin,
|
||||||
|
pre=" CDate temp$csinput = new CDate();",
|
||||||
|
post=" $csinput = new System.DateTime(temp$csinput.getYear(),"
|
||||||
|
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
|
||||||
|
cshin="ref $csinput") CDate &
|
||||||
|
"$csclassname.getCPtr(temp$csinput)"
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The resulting generated proxy code in the <tt>Action</tt> class follows:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
public class Action : IDisposable {
|
||||||
|
...
|
||||||
|
public int doSomething(System.DateTime dateIn, ref System.DateTime dateOut) {
|
||||||
|
CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day);
|
||||||
|
CDate tempdateOut = new CDate();
|
||||||
|
try {
|
||||||
|
int ret = examplePINVOKE.Action_doSomething(swigCPtr,
|
||||||
|
CDate.getCPtr(tempdateIn),
|
||||||
|
CDate.getCPtr(tempdateOut));
|
||||||
|
if (examplePINVOKE.SWIGPendingException.Pending)
|
||||||
|
throw examplePINVOKE.SWIGPendingException.Retrieve();
|
||||||
|
return ret;
|
||||||
|
} finally {
|
||||||
|
dateOut = new System.DateTime(tempdateOut.getYear(),
|
||||||
|
tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static private IntPtr SwigConstructAction(System.DateTime dateIn, ref System.DateTime dateOut) {
|
||||||
|
CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day);
|
||||||
|
CDate tempdateOut = new CDate();
|
||||||
|
try {
|
||||||
|
return examplePINVOKE.new_Action(CDate.getCPtr(tempdateIn), CDate.getCPtr(tempdateOut));
|
||||||
|
} finally {
|
||||||
|
dateOut = new System.DateTime(tempdateOut.getYear(),
|
||||||
|
tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action(System.DateTime dateIn, ref System.DateTime dateOut)
|
||||||
|
: this(Action.SwigConstructAction(dateIn, ref dateOut), true) {
|
||||||
|
if (examplePINVOKE.SWIGPendingException.Pending)
|
||||||
|
throw examplePINVOKE.SWIGPendingException.Retrieve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A few things to note:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li> The "cstype" typemap has changed the parameter type to <tt>System.DateTime</tt> instead of the default generated <tt>CDate</tt> proxy.
|
||||||
|
<li> The non-const <tt>CDate &</tt> type is marshalled as a reference parameter in C# as the date cannot be explicitly set once the object has been created, so a new object is created instead.
|
||||||
|
<li> The code in the 'pre' attribute appears before the intermediary call (<tt>examplePINVOKE.new_Action</tt> / <tt>examplePINVOKE.Action_doSomething</tt>).
|
||||||
|
<li> The code in the 'post' attribute appears after the intermediary call.
|
||||||
|
<li> A try .. finally block is generated with the intermediary call in the try block and 'post' code in the finally block.
|
||||||
|
The alternative of just using a temporary variable for the return value from the intermediary call and the 'post' code being inserted before the
|
||||||
|
return statement is not possible given that the intermediary call and method return comes from a single source (the "csout" typemap).
|
||||||
|
<li> The temporary variables in the "csin" typemaps are called <tt>temp$csin</tt>, where "$csin" is replaced with the parameter name.
|
||||||
|
"$csin" is used to mangle the variable name so that more than one <tt>CDate &</tt> type can be used as a parameter in a method, otherwise two or
|
||||||
|
more local variables with the same name would be generated.
|
||||||
|
<li> The use of the "csin" typemap causes a constructor helper function (<tt>SwigConstructAction</tt>) to be generated.
|
||||||
|
This allows C# code to be called before the intermediary call made in the constructor initialization list.
|
||||||
|
<li> The 'cshin' attribute is required for the <tt>SwigConstructAction</tt> constructor helper function so that the 2nd parameter is declared as <tt>ref dateOut</tt> instead of just <tt>dateOut</tt>.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1854,6 +1854,8 @@ public:
|
||||||
String *return_type = NewString("");
|
String *return_type = NewString("");
|
||||||
String *function_code = NewString("");
|
String *function_code = NewString("");
|
||||||
bool setter_flag = false;
|
bool setter_flag = false;
|
||||||
|
String *pre_code = NewString("");
|
||||||
|
String *post_code = NewString("");
|
||||||
|
|
||||||
if (!proxy_flag)
|
if (!proxy_flag)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1983,6 +1985,22 @@ public:
|
||||||
if ((tm = Getattr(p, "tmap:csin"))) {
|
if ((tm = Getattr(p, "tmap:csin"))) {
|
||||||
substituteClassname(pt, tm);
|
substituteClassname(pt, tm);
|
||||||
Replaceall(tm, "$csinput", arg);
|
Replaceall(tm, "$csinput", arg);
|
||||||
|
String *pre = Getattr(p, "tmap:csin:pre");
|
||||||
|
if (pre) {
|
||||||
|
substituteClassname(pt, pre);
|
||||||
|
Replaceall(pre, "$csinput", arg);
|
||||||
|
if (Len(pre_code) > 0)
|
||||||
|
Printf(pre_code, "\n");
|
||||||
|
Printv(pre_code, pre, NIL);
|
||||||
|
}
|
||||||
|
String *post = Getattr(p, "tmap:csin:post");
|
||||||
|
if (post) {
|
||||||
|
substituteClassname(pt, post);
|
||||||
|
Replaceall(post, "$csinput", arg);
|
||||||
|
if (Len(post_code) > 0)
|
||||||
|
Printf(post_code, "\n");
|
||||||
|
Printv(post_code, post, NIL);
|
||||||
|
}
|
||||||
Printv(imcall, tm, NIL);
|
Printv(imcall, tm, NIL);
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
|
Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
|
||||||
|
|
@ -2005,6 +2023,24 @@ public:
|
||||||
|
|
||||||
// Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
|
// Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
|
||||||
if ((tm = Swig_typemap_lookup_new("csout", n, "", 0))) {
|
if ((tm = Swig_typemap_lookup_new("csout", n, "", 0))) {
|
||||||
|
excodeSubstitute(n, tm, "csout", n);
|
||||||
|
bool is_pre_code = Len(pre_code) > 0;
|
||||||
|
bool is_post_code = Len(post_code) > 0;
|
||||||
|
if (is_pre_code || is_post_code) {
|
||||||
|
Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
|
||||||
|
if (is_post_code) {
|
||||||
|
Insert(tm, 0, "\n try ");
|
||||||
|
Printv(tm, " finally {\n", post_code, "\n }", NIL);
|
||||||
|
} else {
|
||||||
|
Insert(tm, 0, "\n ");
|
||||||
|
}
|
||||||
|
if (is_pre_code) {
|
||||||
|
Insert(tm, 0, pre_code);
|
||||||
|
Insert(tm, 0, "\n");
|
||||||
|
}
|
||||||
|
Insert(tm, 0, "{");
|
||||||
|
Printf(tm, "\n }");
|
||||||
|
}
|
||||||
if (GetFlag(n, "feature:new"))
|
if (GetFlag(n, "feature:new"))
|
||||||
Replaceall(tm, "$owner", "true");
|
Replaceall(tm, "$owner", "true");
|
||||||
else
|
else
|
||||||
|
|
@ -2033,7 +2069,6 @@ public:
|
||||||
Delete(excode);
|
Delete(excode);
|
||||||
}
|
}
|
||||||
Replaceall(tm, "$imcall", imcall);
|
Replaceall(tm, "$imcall", imcall);
|
||||||
excodeSubstitute(n, tm, "csout", n);
|
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
|
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
|
||||||
}
|
}
|
||||||
|
|
@ -2097,6 +2132,8 @@ public:
|
||||||
Printv(proxy_class_code, function_code, NIL);
|
Printv(proxy_class_code, function_code, NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(pre_code);
|
||||||
|
Delete(post_code);
|
||||||
Delete(function_code);
|
Delete(function_code);
|
||||||
Delete(return_type);
|
Delete(return_type);
|
||||||
Delete(imcall);
|
Delete(imcall);
|
||||||
|
|
@ -2113,6 +2150,11 @@ public:
|
||||||
Parm *p;
|
Parm *p;
|
||||||
int i;
|
int i;
|
||||||
String *function_code = NewString("");
|
String *function_code = NewString("");
|
||||||
|
String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the csin typemap has code in the pre or post attributes
|
||||||
|
String *helper_args = NewString("");
|
||||||
|
String *pre_code = NewString("");
|
||||||
|
String *post_code = NewString("");
|
||||||
|
String *im_return_type = NewString("");
|
||||||
bool feature_director = (parentNode(n) && Swig_directorclass(n));
|
bool feature_director = (parentNode(n) && Swig_directorclass(n));
|
||||||
|
|
||||||
Language::constructorHandler(n);
|
Language::constructorHandler(n);
|
||||||
|
|
@ -2127,11 +2169,22 @@ public:
|
||||||
String *imcall = NewString("");
|
String *imcall = NewString("");
|
||||||
|
|
||||||
const String *csattributes = Getattr(n, "feature:cs:attributes");
|
const String *csattributes = Getattr(n, "feature:cs:attributes");
|
||||||
if (csattributes)
|
if (csattributes) {
|
||||||
Printf(function_code, " %s\n", csattributes);
|
Printf(function_code, " %s\n", csattributes);
|
||||||
|
Printf(helper_code, " %s\n", csattributes);
|
||||||
|
}
|
||||||
const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
|
const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
|
||||||
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
|
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
|
||||||
|
|
||||||
|
tm = Getattr(n, "tmap:imtype"); // typemaps were attached earlier to the node
|
||||||
|
String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
|
||||||
|
if (imtypeout)
|
||||||
|
tm = imtypeout;
|
||||||
|
Printf(im_return_type, "%s", tm);
|
||||||
|
|
||||||
Printf(function_code, " %s %s(", methodmods, proxy_class_name);
|
Printf(function_code, " %s %s(", methodmods, proxy_class_name);
|
||||||
|
Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
|
||||||
|
|
||||||
Printv(imcall, imclass_name, ".", mangled_overname, "(", NIL);
|
Printv(imcall, imclass_name, ".", mangled_overname, "(", NIL);
|
||||||
|
|
||||||
/* Attach the non-standard typemaps to the parameter list */
|
/* Attach the non-standard typemaps to the parameter list */
|
||||||
|
|
@ -2174,22 +2227,48 @@ public:
|
||||||
Printf(imcall, ", ");
|
Printf(imcall, ", ");
|
||||||
|
|
||||||
String *arg = makeParameterName(n, p, i, false);
|
String *arg = makeParameterName(n, p, i, false);
|
||||||
|
String *cshin = 0;
|
||||||
|
|
||||||
// Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
|
// Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
|
||||||
if ((tm = Getattr(p, "tmap:csin"))) {
|
if ((tm = Getattr(p, "tmap:csin"))) {
|
||||||
substituteClassname(pt, tm);
|
substituteClassname(pt, tm);
|
||||||
Replaceall(tm, "$csinput", arg);
|
Replaceall(tm, "$csinput", arg);
|
||||||
|
String *pre = Getattr(p, "tmap:csin:pre");
|
||||||
|
if (pre) {
|
||||||
|
substituteClassname(pt, pre);
|
||||||
|
Replaceall(pre, "$csinput", arg);
|
||||||
|
if (Len(pre_code) > 0)
|
||||||
|
Printf(pre_code, "\n");
|
||||||
|
Printv(pre_code, pre, NIL);
|
||||||
|
}
|
||||||
|
String *post = Getattr(p, "tmap:csin:post");
|
||||||
|
if (post) {
|
||||||
|
substituteClassname(pt, post);
|
||||||
|
Replaceall(post, "$csinput", arg);
|
||||||
|
if (Len(post_code) > 0)
|
||||||
|
Printf(post_code, "\n");
|
||||||
|
Printv(post_code, post, NIL);
|
||||||
|
}
|
||||||
|
cshin = Getattr(p, "tmap:csin:cshin");
|
||||||
|
if (cshin)
|
||||||
|
Replaceall(cshin, "$csinput", arg);
|
||||||
Printv(imcall, tm, NIL);
|
Printv(imcall, tm, NIL);
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
|
Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add parameter to proxy function */
|
/* Add parameter to proxy function */
|
||||||
if (gencomma)
|
if (gencomma) {
|
||||||
Printf(function_code, ", ");
|
Printf(function_code, ", ");
|
||||||
|
Printf(helper_code, ", ");
|
||||||
|
Printf(helper_args, ", ");
|
||||||
|
}
|
||||||
Printf(function_code, "%s %s", param_type, arg);
|
Printf(function_code, "%s %s", param_type, arg);
|
||||||
|
Printf(helper_code, "%s %s", param_type, arg);
|
||||||
|
Printf(helper_args, "%s", cshin ? cshin : arg);
|
||||||
++gencomma;
|
++gencomma;
|
||||||
|
|
||||||
|
Delete(cshin);
|
||||||
Delete(arg);
|
Delete(arg);
|
||||||
Delete(param_type);
|
Delete(param_type);
|
||||||
p = Getattr(p, "tmap:in:next");
|
p = Getattr(p, "tmap:in:next");
|
||||||
|
|
@ -2198,6 +2277,7 @@ public:
|
||||||
Printf(imcall, ")");
|
Printf(imcall, ")");
|
||||||
|
|
||||||
Printf(function_code, ")");
|
Printf(function_code, ")");
|
||||||
|
Printf(helper_code, ")");
|
||||||
|
|
||||||
/* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */
|
/* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */
|
||||||
Hash *attributes = NewHash();
|
Hash *attributes = NewHash();
|
||||||
|
|
@ -2221,10 +2301,40 @@ public:
|
||||||
Printv(function_code, " ", construct_tm, NIL);
|
Printv(function_code, " ", construct_tm, NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Replaceall(function_code, "$imcall", imcall);
|
|
||||||
excodeSubstitute(n, function_code, "csconstruct", attributes);
|
excodeSubstitute(n, function_code, "csconstruct", attributes);
|
||||||
|
|
||||||
|
bool is_pre_code = Len(pre_code) > 0;
|
||||||
|
bool is_post_code = Len(post_code) > 0;
|
||||||
|
if (is_pre_code || is_post_code) {
|
||||||
|
Printf(helper_code, " {\n");
|
||||||
|
if (is_pre_code) {
|
||||||
|
Printv(helper_code, pre_code, "\n", NIL);
|
||||||
|
}
|
||||||
|
if (is_post_code) {
|
||||||
|
Printf(helper_code, " try {\n");
|
||||||
|
Printv(helper_code, " return ", imcall, ";\n", NIL);
|
||||||
|
Printv(helper_code, " } finally {\n", post_code, "\n }", NIL);
|
||||||
|
} else {
|
||||||
|
Printv(helper_code, " return ", imcall, ";", NIL);
|
||||||
|
}
|
||||||
|
Printf(helper_code, "\n }\n");
|
||||||
|
String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args);
|
||||||
|
String *im_outattribute = Getattr(n, "tmap:imtype:outattributes");
|
||||||
|
if (im_outattribute)
|
||||||
|
Printf(proxy_class_code, " %s\n", im_outattribute);
|
||||||
|
Printv(proxy_class_code, helper_code, "\n", NIL);
|
||||||
|
Replaceall(function_code, "$imcall", helper_name);
|
||||||
|
Delete(helper_name);
|
||||||
|
} else {
|
||||||
|
Replaceall(function_code, "$imcall", imcall);
|
||||||
|
}
|
||||||
|
|
||||||
Printv(proxy_class_code, function_code, "\n", NIL);
|
Printv(proxy_class_code, function_code, "\n", NIL);
|
||||||
|
|
||||||
|
Delete(helper_args);
|
||||||
|
Delete(im_return_type);
|
||||||
|
Delete(pre_code);
|
||||||
|
Delete(post_code);
|
||||||
Delete(construct_tm);
|
Delete(construct_tm);
|
||||||
Delete(attributes);
|
Delete(attributes);
|
||||||
Delete(overloaded_name);
|
Delete(overloaded_name);
|
||||||
|
|
@ -2340,6 +2450,8 @@ public:
|
||||||
String *overloaded_name = getOverloadedName(n);
|
String *overloaded_name = getOverloadedName(n);
|
||||||
String *func_name = NULL;
|
String *func_name = NULL;
|
||||||
bool setter_flag = false;
|
bool setter_flag = false;
|
||||||
|
String *pre_code = NewString("");
|
||||||
|
String *post_code = NewString("");
|
||||||
|
|
||||||
if (l) {
|
if (l) {
|
||||||
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
|
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
|
||||||
|
|
@ -2425,6 +2537,22 @@ public:
|
||||||
if ((tm = Getattr(p, "tmap:csin"))) {
|
if ((tm = Getattr(p, "tmap:csin"))) {
|
||||||
substituteClassname(pt, tm);
|
substituteClassname(pt, tm);
|
||||||
Replaceall(tm, "$csinput", arg);
|
Replaceall(tm, "$csinput", arg);
|
||||||
|
String *pre = Getattr(p, "tmap:csin:pre");
|
||||||
|
if (pre) {
|
||||||
|
substituteClassname(pt, pre);
|
||||||
|
Replaceall(pre, "$csinput", arg);
|
||||||
|
if (Len(pre_code) > 0)
|
||||||
|
Printf(pre_code, "\n");
|
||||||
|
Printv(pre_code, pre, NIL);
|
||||||
|
}
|
||||||
|
String *post = Getattr(p, "tmap:csin:post");
|
||||||
|
if (post) {
|
||||||
|
substituteClassname(pt, post);
|
||||||
|
Replaceall(post, "$csinput", arg);
|
||||||
|
if (Len(post_code) > 0)
|
||||||
|
Printf(post_code, "\n");
|
||||||
|
Printv(post_code, post, NIL);
|
||||||
|
}
|
||||||
Printv(imcall, tm, NIL);
|
Printv(imcall, tm, NIL);
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
|
Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
|
||||||
|
|
@ -2446,13 +2574,30 @@ public:
|
||||||
|
|
||||||
// Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in module class)
|
// Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in module class)
|
||||||
if ((tm = Swig_typemap_lookup_new("csout", n, "", 0))) {
|
if ((tm = Swig_typemap_lookup_new("csout", n, "", 0))) {
|
||||||
|
excodeSubstitute(n, tm, "csout", n);
|
||||||
|
bool is_pre_code = Len(pre_code) > 0;
|
||||||
|
bool is_post_code = Len(post_code) > 0;
|
||||||
|
if (is_pre_code || is_post_code) {
|
||||||
|
Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
|
||||||
|
if (is_post_code) {
|
||||||
|
Insert(tm, 0, "\n try ");
|
||||||
|
Printv(tm, " finally {\n", post_code, "\n }", NIL);
|
||||||
|
} else {
|
||||||
|
Insert(tm, 0, "\n ");
|
||||||
|
}
|
||||||
|
if (is_pre_code) {
|
||||||
|
Insert(tm, 0, pre_code);
|
||||||
|
Insert(tm, 0, "\n");
|
||||||
|
}
|
||||||
|
Insert(tm, 0, "{");
|
||||||
|
Printf(tm, "\n }");
|
||||||
|
}
|
||||||
if (GetFlag(n, "feature:new"))
|
if (GetFlag(n, "feature:new"))
|
||||||
Replaceall(tm, "$owner", "true");
|
Replaceall(tm, "$owner", "true");
|
||||||
else
|
else
|
||||||
Replaceall(tm, "$owner", "false");
|
Replaceall(tm, "$owner", "false");
|
||||||
substituteClassname(t, tm);
|
substituteClassname(t, tm);
|
||||||
Replaceall(tm, "$imcall", imcall);
|
Replaceall(tm, "$imcall", imcall);
|
||||||
excodeSubstitute(n, tm, "csout", n);
|
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
|
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
|
||||||
}
|
}
|
||||||
|
|
@ -2516,6 +2661,8 @@ public:
|
||||||
Printv(module_class_code, function_code, NIL);
|
Printv(module_class_code, function_code, NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(pre_code);
|
||||||
|
Delete(post_code);
|
||||||
Delete(function_code);
|
Delete(function_code);
|
||||||
Delete(return_type);
|
Delete(return_type);
|
||||||
Delete(imcall);
|
Delete(imcall);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue