<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.stridewiki.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Root</id>
	<title>STRIDE Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.stridewiki.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Root"/>
	<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Special:Contributions/Root"/>
	<updated>2026-04-28T02:04:39Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.10</generator>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Scripting_Overview&amp;diff=4012</id>
		<title>Studio:Scripting Overview</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Scripting_Overview&amp;diff=4012"/>
		<updated>2008-02-29T01:06:28Z</updated>

		<summary type="html">&lt;p&gt;Root: New page:  STRIDE affords you a number of different options for automating your  testing, including datasets and scripts. Each option provides a unique  set of testing capabilities. When conditional...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
STRIDE affords you a number of different options for automating your&lt;br /&gt;
&lt;br /&gt;
testing, including datasets and scripts. Each option provides a unique&lt;br /&gt;
&lt;br /&gt;
set of testing capabilities. When conditional logic, event processing,&lt;br /&gt;
&lt;br /&gt;
user intervention, or other complex operations are required, scripts may&lt;br /&gt;
&lt;br /&gt;
be the most appropriate option.&lt;br /&gt;
&lt;br /&gt;
Using scripts to drive test scenarios or to simulate missing components&lt;br /&gt;
&lt;br /&gt;
has traditionally been difficult, if not impossible, when the unit under&lt;br /&gt;
&lt;br /&gt;
test is located on the target platform. Moreover, scripting languages&lt;br /&gt;
&lt;br /&gt;
and the C language do not necessarily mix well. Because of these difficulties,&lt;br /&gt;
&lt;br /&gt;
developers rarely use scripts for testing and integration, despite the&lt;br /&gt;
&lt;br /&gt;
potential benefits.&lt;br /&gt;
&lt;br /&gt;
STRIDE makes it possible to use scripts written in any scripting language&lt;br /&gt;
&lt;br /&gt;
to test your software units regardless of whether they are located on&lt;br /&gt;
&lt;br /&gt;
the host, target, or both. There are two common use cases for using scripts&lt;br /&gt;
&lt;br /&gt;
to integrate and test:&lt;br /&gt;
&lt;br /&gt;
*  To drive the testing of a unit or units by calling functions&lt;br /&gt;
&lt;br /&gt;
and/or sending commands and receiving messages.&lt;br /&gt;
*  To simulate a missing function or other component so an interdependent&lt;br /&gt;
unit can be tested.&lt;br /&gt;
&lt;br /&gt;
To illustrate these two use cases, consider a hypothetical embedded&lt;br /&gt;
&lt;br /&gt;
application containing three functions: A, B, and C. A calls B and B calls&lt;br /&gt;
&lt;br /&gt;
C as shown on the left in the diagram below. Suppose that you developed&lt;br /&gt;
&lt;br /&gt;
function B and you are ready to test it, but function C is not yet completed.&lt;br /&gt;
&lt;br /&gt;
One solution, which would allow you to continue testing regardless of&lt;br /&gt;
&lt;br /&gt;
the availability of function C, is to use scripts as shown on the right&lt;br /&gt;
&lt;br /&gt;
in the diagram below. One script simulates the missing function C (Use&lt;br /&gt;
&lt;br /&gt;
Case #2) while the other drives the testing of function B (Use Case #1).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:Overview_Scripting.png]]&lt;br /&gt;
&lt;br /&gt;
As implied in the diagram, the fact that scripts replace functions A&lt;br /&gt;
&lt;br /&gt;
and C does not change the interfaces with function B; via STRIDE, interfaces&lt;br /&gt;
&lt;br /&gt;
defined in your embedded application are available at the source level&lt;br /&gt;
&lt;br /&gt;
in your favorite scripting language. In addition, function B could be&lt;br /&gt;
&lt;br /&gt;
on the target application, whereas the scripts replacing functions A and&lt;br /&gt;
&lt;br /&gt;
C are running on the host.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Main_Page&amp;diff=4008</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Main_Page&amp;diff=4008"/>
		<updated>2008-02-28T19:44:50Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the new S2 Technologies&amp;amp;trade; &#039;&#039;&#039;STRIDE&#039;&#039;&#039;&amp;amp;trade;&#039;&#039;&#039; Support Wiki&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This site is currently a &#039;&#039;&#039;WORK IN PROGRESS&#039;&#039;&#039;. It is expected to be available for general consumption by end of February (2008) with the STRIDE &#039;&#039;&#039;Moonlight&#039;&#039;&#039; beta release. &lt;br /&gt;
Customer additions are welcome and encouraged.  Please read the &#039;&#039;&#039;[[S2 Wiki Support|S2 Wiki Support Policies]]&#039;&#039;&#039;, &#039;&#039;&#039;[[Help:How to add a topic|How to add a topic]]&#039;&#039;&#039; and &#039;&#039;&#039;[[Help:Contents|Help]]&#039;&#039;&#039; pages for guidelines and instructions on editing.  You must &#039;&#039;&#039;[[Special:Userlogin|log in or create an account]]&#039;&#039;&#039; before you can edit a page.&lt;br /&gt;
&lt;br /&gt;
Please select a topic or category heading below, or enter a search string in the Search field to the left.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
{|&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
{|cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;vertical-align:top;border:1px solid #bcc&amp;quot;&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Deploying STRIDE|Deploying STRIDE]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Test Utilities|Test Utilities]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Frameworks|Frameworks]]&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[Installing STRIDE]]&lt;br /&gt;
* [[Integrating STRIDE]]&lt;br /&gt;
* [[Verifying Installation]]&lt;br /&gt;
* [[Proof of Concept]]&lt;br /&gt;
* [[Framework| Framework]]&lt;br /&gt;
* [[Training]]&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[Host Apps]]&lt;br /&gt;
* [[Test Classes]]&lt;br /&gt;
* [[Test Functions]]&lt;br /&gt;
* [[Test Runners]]&lt;br /&gt;
* [[Components]]&lt;br /&gt;
* [[Templates]]&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[Using Frameworks]]&lt;br /&gt;
* [[Creating Frameworks]]&lt;br /&gt;
* [[Provided Frameworks]]&lt;br /&gt;
* [[Using Packages]]&lt;br /&gt;
* [[Creating Packages]]&lt;br /&gt;
* [[Provided Packages]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Training|Training]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Application Notes|Application Notes]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Release Notes|Release Notes]]&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Overview]]&lt;br /&gt;
*[[STRIDE Quick Start]]&lt;br /&gt;
*[[Target Test Code]]&lt;br /&gt;
*[[Interface Instrumentation]]&lt;br /&gt;
*[[Test Scripts]]&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
*[[:Category:SCL|SCL]]&lt;br /&gt;
*[[:Category:Scripting|Scripting]]&lt;br /&gt;
*[[:Category:Troubleshooting|Troubleshooting]]&lt;br /&gt;
*[[:Category:FAQ|FAQ]]&lt;br /&gt;
*[[New Appnotes Docs]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[STRIDE 2.1.00xx | STRIDE 2.1.00xx (D Street)]]&lt;br /&gt;
* [[2.1.0201 | STRIDE 2.1.02xx (Moonlight)]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3571</id>
		<title>Category:SCL</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3571"/>
		<updated>2008-02-05T23:56:12Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Where should these topics go? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Pointers===&lt;br /&gt;
* [[Can STRIDE marshal both data and pointers?]]&lt;br /&gt;
* [[Can an array be cast to a pointer?]]&lt;br /&gt;
* [[Casting and pointers]]&lt;br /&gt;
* [[Accessing target data while processing a proxy call]]&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
* [[How do I apply an SCL pragma to an array?]]&lt;br /&gt;
* [[Assigning array elements]]&lt;br /&gt;
* [[How does the STRIDE compiler handle zero-length arrays?]]&lt;br /&gt;
&lt;br /&gt;
===Callbacks===&lt;br /&gt;
* [[Accessing the return value of a function using scripting]]&lt;br /&gt;
* [[Are multiple callbacks possible?]]&lt;br /&gt;
* [[Callback functions in Perl scripts]]&lt;br /&gt;
&lt;br /&gt;
===Workarounds===&lt;br /&gt;
* [[How do I work around variable arguments for stubs?]]&lt;br /&gt;
* [[Understanding SCL conflicts]]&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
* [[Applying pragmas up and down type chains]]&lt;br /&gt;
&lt;br /&gt;
===Miscellaneous SCL topics===&lt;br /&gt;
* [[Working with &amp;quot;default&amp;quot; candidates]]&lt;br /&gt;
* [[Advantages and disadvantages of &amp;quot;default&amp;quot; candidates]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Working_with_%22default%22_candidates&amp;diff=3570</id>
		<title>Studio:Working with &quot;default&quot; candidates</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Working_with_%22default%22_candidates&amp;diff=3570"/>
		<updated>2008-02-05T23:55:44Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;scl_ptr_flist() serves as a &amp;quot;shorthand&amp;quot; method of declaring a &amp;quot;default&amp;quot; candidate.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: When using scl_ptr_flist() to define candidates, the function pointer prototypes are defined internally within STRIDE, rather than by the user. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;// function pointer typedef&amp;lt;br&amp;gt;&lt;br /&gt;
 typedef void (*FPtr) (int, char);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo(FPtr *pFPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo1(FPtr *pFPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo2(FPtr *pFPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo3(FPtr *pFPtr);&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 // candidate prototypes &amp;lt;br&amp;gt;&lt;br /&gt;
 void C1(int x, char y);&amp;lt;br&amp;gt;&lt;br /&gt;
 void C2(int x, char y);&amp;lt;br&amp;gt;&lt;br /&gt;
 void C3(int x, char y);&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 // pragmatize candidate prototypes&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(C1)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(C2)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(C3)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to declare a &amp;quot;default&amp;quot; candidate using scl_ptr_flist()&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
There are several methods of declaring a &amp;quot;default&amp;quot; candidate using scl_ptr_flist(). Each method is explained below.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 1: Candidate list declaration using predefined function prototypes&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_flist(*foo.pFPtr, C1, C2, C3)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The candidates&#039; (C1, C2, C3) prototypes are defined and pragmatized, and proxies/stubs will be generated. In the parent function (the function that contains the function pointer PFptr) will use a for loop to search through the static table to bind the function pointer with the SMID or vice versa. The command and response payloads of the candidate functions (C1, C2, C3) can be captured via tracing.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 2: Candidate list declaration using shorthand method&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo1)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_flist(*foo1.pFPtr, &amp;quot;cand1&amp;quot;)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Default&amp;quot; proxies/stubs will be generated for the name in quotes in scl_ptr_flist() &amp;quot;cand1&amp;quot; in the example above. The command and response payloads of the candidate functions (e.g., &amp;quot;cand1&amp;quot;) can be captured via tracing.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 3: Candidate list declaration using combination of predefined functions and shorthand method&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo2)&lt;br /&gt;
 #pragma scl_ptr_flist(*foo2.pFPtr, &amp;quot;cand4&amp;quot;, C2)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The candidate &amp;quot;cand4&amp;quot; is interpreted by STRIDE as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt; void cand4(int p1, char p2);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(cand4)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Default&amp;quot; proxies/stubs will be generated for the name in quotes in scl_ptr_flist() &amp;quot;cand4&amp;quot; in the example above. The command and response payloads of the candidate functions (e.g., &amp;quot;cand4&amp;quot;) can be captured via tracing.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 4: &amp;quot;Default&amp;quot; candidate declaration&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo3)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_flist(*foo3.pFPtr, &amp;quot;def_cand&amp;quot;)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The candidate &amp;quot;def_cand&amp;quot; is interpreted by STRIDE as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;void def_cand(int p1, char p2);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(def_cand)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;default&amp;quot; proxy/stub will be generated for def_cand. The parent function will not use a for loop and the proxy will replace the existing function pointer in the table with the passed-in function pointer. The command and response payloads of any function prototype with the identical signature to def_cand can be captured via tracing.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Using_printf&amp;diff=3569</id>
		<title>Studio:Using printf</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Using_printf&amp;diff=3569"/>
		<updated>2008-02-05T23:55:24Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In some cases, printf is a quick and easy way to add debug information to your code. When using STRIDE, it is helpful to have the printf output redirected to the trace view window, so that the printf output is in sequence with all the function calls, messages, and trace points. Having printf output sent to the trace views not only consolidates all the debug information into one place — the trace view — it also helps to understand the sequence of events.&lt;br /&gt;
&lt;br /&gt;
STRIDE provides a simple runtime command, srTraceStr, which sends strings to the trace window; however, replacing printf statements with srTraceStr in the source code can require a great deal of effort, which may not be worth it. A much simpler option is to use a macro definition to globally replace printf with srTraceStr. In addition, srTraceStr and printf&#039;s argument lists do not match exactly; therefore, parameter mapping is required. srTraceStr&#039;s syntax is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;srEXPORT srWORD srSTDCALL srTraceStr( srWORD      wSTID,&lt;br /&gt;
                                       srCHAR      *szString,&lt;br /&gt;
                                       srLevel_e   eLevel );&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
szString is the string to be displayed in the trace view. In addition, srTraceStr contains a filtering level for the host trace view. Since printf does not offer any level of trace view filtering, it can be mapped to a single level. In most cases, level 0 is appropriate since there is no need to filter printf statements; usually you want to see them, as they are generally there for a reason.&lt;br /&gt;
&lt;br /&gt;
srTraceStr&#039;s other parameter, wSTID, is a bit more complicated. A STID has to be created before srTraceStr can be called. The following two options are available:&lt;br /&gt;
*A STID specific to the printf tracing could be created in the target initialization code. In other words, the “STRIDE printf” would have its own STID, allowing it to be easily filtered out in the trace view if required.&lt;br /&gt;
*Alternately, the STID used for the intercept module could be reused. Since the scope of the “IM STID” is limited to the xxxIM.c file, the “STRIDE printf” would have to be part of this file. The intercept module is automatically generated, and therefore should not be modified; however, the example below demonstrates how the “IM STID” can be reused without having to modify the automatically-generated intercept module code.&lt;br /&gt;
&lt;br /&gt;
The following macro replaces printf with a function called stride_printf :&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define printf stride_printf&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we have to implement the stride_printf function. Since we replaced printf,we have to address variable arguments. The following example demonstrates a possible implementation:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static __inline srWORD stride_printf(char *s, ...)&lt;br /&gt;
 {&lt;br /&gt;
    srWORD ret;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_list args;&amp;lt;br&amp;gt;&lt;br /&gt;
    char str[MAX_STRIDE_PRINTF_SIZE];&amp;lt;br&amp;gt;&lt;br /&gt;
    va_start(args, s);&amp;lt;br&amp;gt;&lt;br /&gt;
    sprintf(str, s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
    ret = srTraceStr (wSTID, (srCHAR*) str, srLEVEL_0);&amp;lt;br&amp;gt;&lt;br /&gt;
    return ret;&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the intercept module STID (wSTID) was used.&lt;br /&gt;
&lt;br /&gt;
Now that we have made the change, the printf output will go to the STRIDE trace view — however, what if STRIDE is not being used but you still want to see the printf output? This can be done simply by adding a small function which allows switching between the normal printf and stride_printf; by exposing this interface in STRIDE, the output can be controlled regardless of whether or not you are using STRIDE. &lt;br /&gt;
 &amp;lt;tt&amp;gt;void stride_printf_set(stride_printf_flag_t flag)&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
   stride_printf_on = flag;&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the STRIDE printf function has to change slightly to add a “normal” printf:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;srWORD stride_printf(char *s, ...)&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
    srWORD ret = srOK;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_list args;&amp;lt;br&amp;gt;&lt;br /&gt;
    char str[MAX_STRIDE_PRINTF_SIZE];&amp;lt;br&amp;gt;&lt;br /&gt;
    va_start(args, s);&amp;lt;br&amp;gt;&lt;br /&gt;
    if ((!(stride_printf_on &amp;amp; STRIDE_PRINTF)) ||&amp;lt;br&amp;gt;&lt;br /&gt;
          (stride_printf_on &amp;amp; OS_PRINTF))&amp;lt;br&amp;gt;&lt;br /&gt;
    {&amp;lt;br&amp;gt;    &lt;br /&gt;
       printf(s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
    }&amp;lt;br&amp;gt;&lt;br /&gt;
    if (stride_printf_on &amp;amp; STRIDE_PRINTF)&amp;lt;br&amp;gt;&lt;br /&gt;
    {&amp;lt;br&amp;gt;&lt;br /&gt;
       sprintf(str, s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
       ret = srTraceStr (wSTID, (srCHAR*) str, srLEVEL_0);&amp;lt;br&amp;gt;&lt;br /&gt;
    }   &amp;lt;br&amp;gt;&lt;br /&gt;
    return ret;&amp;lt;br&amp;gt;&lt;br /&gt;
   }&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sample header files&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Two header files are required in order to use printf to add debug information to your code: a header file which redefines printf to stride_printf, and a header file containing the stride_printf implementation as an inline function as well as the SCL pragmas for STRIDE.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Redefining printf to stride_printf&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
This header file should be included in one of the general include files, which in turn is included in all the source files to limit source code modifications.&lt;br /&gt;
  &amp;lt;tt&amp;gt;#ifndef STRIDE_PRINTF_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #define STRIDE_PRINTF_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  extern &amp;quot;C&amp;quot; {&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #define MAX_STRIDE_PRINTF_SIZE  255&amp;lt;br&amp;gt;&lt;br /&gt;
  #define OS_PRINTF                 1&amp;lt;br&amp;gt;&lt;br /&gt;
  #define STRIDE_PRINTF             2&amp;lt;br&amp;gt;&lt;br /&gt;
  extern srWORD stride_printf(char *s);&amp;lt;br&amp;gt;&lt;br /&gt;
  /* Redefine printf to stride_printf */&amp;lt;br&amp;gt;&lt;br /&gt;
  #define printf stride_printf&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif  /* STRIDE_PRINTF_H */&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementing stride_printf as an inline function and SCL pragmas&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The stride_printf_scl.h file is included in the STRIDE workspace. It contains the stride_printf implementation as an inline function as well as the SCL pragmas for STRIDE.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;tt&amp;gt;#ifndef STRIDE_PRINTF_SCL_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #define STRIDE_PRINTF_SCL_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  extern &amp;quot;C&amp;quot; {&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdarg.h&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  #include &amp;quot;stride_printf.h&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
  static unsigned char stride_printf_on = OS_PRINTF;&amp;lt;br&amp;gt;&lt;br /&gt;
  extern srWORD   wSTID;&amp;lt;br&amp;gt;&lt;br /&gt;
  static __inline void stride_printf_set(unsigned char flag)&amp;lt;br&amp;gt;&lt;br /&gt;
  {&amp;lt;br&amp;gt;&lt;br /&gt;
   stride_printf_on = flag;&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #undef printf&amp;lt;br&amp;gt;&lt;br /&gt;
  static __inline srWORD stride_printf(char *s, ...)&amp;lt;br&amp;gt;&lt;br /&gt;
  {&amp;lt;br&amp;gt;&lt;br /&gt;
    srWORD ret = srOK;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_list args;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_start(args, s);&amp;lt;br&amp;gt;&lt;br /&gt;
    if ((!(stride_printf_on &amp;amp; STRIDE_PRINTF)) ||&amp;lt;br&amp;gt;&lt;br /&gt;
          (stride_printf_on &amp;amp; OS_PRINTF))&amp;lt;br&amp;gt;&lt;br /&gt;
    {    &amp;lt;br&amp;gt;&lt;br /&gt;
       printf(s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
    }&amp;lt;br&amp;gt;&lt;br /&gt;
    if (stride_printf_on &amp;amp; STRIDE_PRINTF)&amp;lt;br&amp;gt;&lt;br /&gt;
    {&amp;lt;br&amp;gt;&lt;br /&gt;
       char str[MAX_STRIDE_PRINTF_SIZE];&amp;lt;br&amp;gt;&lt;br /&gt;
       sprintf(str, s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
       ret = srTraceStr (wSTID, (srCHAR*) str, srLEVEL_0);&amp;lt;br&amp;gt;&lt;br /&gt;
    }   &amp;lt;br&amp;gt;&lt;br /&gt;
    return ret;&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef _SCL&amp;lt;br&amp;gt;&lt;br /&gt;
  #pragma scl_function(stride_printf_set)&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif  /* STRIDE_PRINTF_SCL_H */&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_to_generate_a_preprocessor_(.i)_file_for_analysis&amp;diff=3568</id>
		<title>Studio:How to generate a preprocessor (.i) file for analysis</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_to_generate_a_preprocessor_(.i)_file_for_analysis&amp;diff=3568"/>
		<updated>2008-02-05T23:55:09Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Preprocessing individual files&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can run the preprocessor on one or more header files to generate .i files, which can then be used for analysis. To do this from within Studio, select one or more top-level header files, right-click, and choose &#039;&#039;&#039;Preprocess&#039;&#039;&#039;. &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: You will need to rename the file to have a .h extension.&lt;br /&gt;
&lt;br /&gt;
Only the selected files are compiled, and preprocessed (.i) files are generated for them. During the compilation, the workspace settings for #defines and include paths are in effect. Existing databases are not affected. &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The #include &amp;lt;stdarg.h&amp;gt; will require the workspace to have a valid pointer (usually to the Microsoft C includes directory).&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_do_I_access_global_variables%3F&amp;diff=3567</id>
		<title>Studio:How do I access global variables?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_do_I_access_global_variables%3F&amp;diff=3567"/>
		<updated>2008-02-05T23:54:57Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE allows you to call functions and send messages on the target, which is in most cases all you need for validation. However, in some cases it might be necessary to read or modify global variables or certain memory locations. If there are API functions available to access the global variables or read memory, those APIs could be exposed to STRIDE and used. If no such API calls are available, they can be added; this requires changes to the target code. Although STRIDE doesn’t directly support accessing target memory with simple helper functions, you can easily access target information without changing the target code by adding code to a header file containing SCL pragmas.&lt;br /&gt;
&lt;br /&gt;
This header file would then be included in the STRIDE workspace, and therefore included in the intercept module. It would not be required to include the header file in any of the customer target code, nor would modifications to the customer code be required. Since the function is known to the intercept module and the intercept module is the only one calling the function, it could be static and therefore have no impact on the rest of the code. The following demonstrates a header file which is included in the STRIDE workspace and subsequently in the intercept module; the function is defined as static, since its scope is limited to the intercept module.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example: Reading a number of bytes from the target&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;static  void SCL_get_num_bytes ( void *ptr, unsigned char* data, int num_bytes)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;{ &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;    memcpy ( data, ptr, num_bytes ); &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;} &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reading and writing global data&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Another application is to read and write global data. For example, we could have a global state variable. Either the header file which defines the global state variable could be included, or an external definition could be added to the header file. The first option is preferred; in some cases the global state variable definition could be in a .c file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example: STRIDE header file&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/* extern definition for global */&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;extern int global_state&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/* helper function to set the state */&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;static void SCL_set_state(int state)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; { &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; global_state = state; &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; } &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; /* helper function to get (read) the state */ &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; static  int SCL_get_state(void) &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; { &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; return global_state;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; } &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Delegating_ISHELL_SendEvent&amp;diff=3566</id>
		<title>Studio:Delegating ISHELL SendEvent</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Delegating_ISHELL_SendEvent&amp;diff=3566"/>
		<updated>2008-02-05T23:54:42Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When trying to dynamically intercept a call for the application under test, intercepting only the call/method of interest was difficult when delegating the IShell Virtual Table, as it allows all methods to be intercepted for all callers.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delegating the user&#039;s call to the IShell helper macro ISHELL_SendEvent is a better method. ISHELL_SendEvent is defined in AEEShell.h as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define ISHELL_SendEvent(p,cls,ec,wp,dw)&amp;lt;br&amp;gt;&lt;br /&gt;
 GET_PVTBL(p,IShell)-&amp;gt;SendEvent(p,0,cls,ec,wp,dw)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This requires a small amount of instrumentation to the calling application, essentially to define the Group ID and include IM.h. You must also complete the following steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure that the calling application is using the helper macro to call the Send event.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add the following code to the AEEShell.h file instead of the #ifdef _SCL conditional block:&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#undef ISHELL_SendEvent&amp;lt;br&amp;gt;&lt;br /&gt;
 int ISHELL_SendEvent(IShell *po, AEECLSID cls, AEEEvent eCode, uint16 wParam, uint32 dwParam);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(ISHELL_SendEvent)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_opaque(ISHELL_SendEvent,po)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create a user-mangled dynamic delegate for the function ISHELL_SendEvent.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add the instrumentation to the calling application&#039;s code:&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#ifdef srIMON&amp;lt;br&amp;gt;&lt;br /&gt;
 #define &amp;lt;groupid-name&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;name&amp;gt;IM.h&amp;lt;br&amp;gt;&lt;br /&gt;
 #endif&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows you to dynamically intercept the call for the application under test.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Main_Page&amp;diff=3564</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Main_Page&amp;diff=3564"/>
		<updated>2008-02-05T22:01:54Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the new S2 Technologies&amp;amp;trade; &#039;&#039;&#039;STRIDE&#039;&#039;&#039;&amp;amp;trade;&#039;&#039;&#039; Support Wiki&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This site is currently a &#039;&#039;&#039;WORK IN PROGRESS&#039;&#039;&#039;. It is expected to be available for general consumption by end of February (2008) with the STRIDE &#039;&#039;&#039;Moonlight&#039;&#039;&#039; beta release. &lt;br /&gt;
Customer additions are welcome and encouraged.  Please read the &#039;&#039;&#039;[[S2 Wiki Support|S2 Wiki Support Policies]]&#039;&#039;&#039;, &#039;&#039;&#039;[[Help:How to add a topic|How to add a topic]]&#039;&#039;&#039; and &#039;&#039;&#039;[[Help:Contents|Help]]&#039;&#039;&#039; pages for guidelines and instructions on editing.  You must &#039;&#039;&#039;[[Special:Userlogin|log in or create an account]]&#039;&#039;&#039; before you can edit a page.&lt;br /&gt;
&lt;br /&gt;
Please select a topic or category heading below, or enter a search string in the Search field to the left.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
{|&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
{|cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;vertical-align:top;border:1px solid #bcc&amp;quot;&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Deploying STRIDE|Deploying STRIDE]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Test Utilities|Test Utilities]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Frameworks|Frameworks]]&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[Installing STRIDE]]&lt;br /&gt;
* [[Integrating STRIDE]]&lt;br /&gt;
* [[Verifying Installation]]&lt;br /&gt;
* [[Proof of Concept]]&lt;br /&gt;
* [[Framework| Framework]]&lt;br /&gt;
* [[Training]]&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[Host Apps]]&lt;br /&gt;
* [[Test Classes]]&lt;br /&gt;
* [[Test Functions]]&lt;br /&gt;
* [[Test Runners]]&lt;br /&gt;
* [[Components]]&lt;br /&gt;
* [[Templates]]&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[Using Frameworks]]&lt;br /&gt;
* [[Creating Frameworks]]&lt;br /&gt;
* [[Provided Frameworks]]&lt;br /&gt;
* [[Using Packages]]&lt;br /&gt;
* [[Creating Packages]]&lt;br /&gt;
* [[Provided Packages]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Training|Training]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Application Notes|Application Notes]]&lt;br /&gt;
! style=&amp;quot;margin:0;background:#cedff2;font-size:120%;font-weight:bold;border:1px solid #a3b0bf;text-align:left;color:#000;padding:0.2em 0.4em;&amp;quot; | [[:Category:Release Notes|Release Notes]]&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Overview]]&lt;br /&gt;
*[[Hello Stride]]&lt;br /&gt;
*[[Interface Instrumentation]]&lt;br /&gt;
*[[Target Test Code]]&lt;br /&gt;
*[[Test Scripts]]&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
*[[:Category:SCL|SCL]]&lt;br /&gt;
*[[:Category:Scripting|Scripting]]&lt;br /&gt;
*[[:Category:Troubleshooting|Troubleshooting]]&lt;br /&gt;
*[[:Category:FAQ|FAQ]] &lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
* [[STRIDE 2.1.00xx | STRIDE 2.1.00xx (D Street)]]&lt;br /&gt;
* [[2.1.0201 | STRIDE 2.1.02xx (Moonlight)]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_to_define_message_structures&amp;diff=3561</id>
		<title>Studio:How to define message structures</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_to_define_message_structures&amp;diff=3561"/>
		<updated>2008-02-05T21:56:36Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following rules make it easier to process unions and select the active member(s) within a union or nested unions, as well as making it easier to transfer data between tasks.&lt;br /&gt;
* Have a one-to-one correlation between disciminants and union members.&lt;br /&gt;
* The order of enums for discriminants matches with the order of members within the union.&lt;br /&gt;
* In the case of nested unions, each union should have its own discriminant.&lt;br /&gt;
* Use inline data instead of pointers.&lt;br /&gt;
&lt;br /&gt;
Below is an example:&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
    DEVICE_NAME,&amp;lt;br&amp;gt;&lt;br /&gt;
    INQUIRY,&amp;lt;br&amp;gt;&lt;br /&gt;
    SD,&amp;lt;br&amp;gt;&lt;br /&gt;
    SECURITY,&amp;lt;br&amp;gt;&lt;br /&gt;
    CONN, &amp;lt;br&amp;gt;&lt;br /&gt;
   } app_opcodes_t;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corresponding message structure is as follows:&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
    ros_hdr_t  ros_hdr;&amp;lt;br&amp;gt;&lt;br /&gt;
    vris_hdr_t  vris_hdr;&amp;lt;br&amp;gt;&lt;br /&gt;
    app_hdr_t  app_hdr;&amp;lt;br&amp;gt;&lt;br /&gt;
 union&amp;lt;br&amp;gt;&lt;br /&gt;
      { &amp;lt;br&amp;gt;&lt;br /&gt;
        app_name_msg_t   app_name_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_inquiry_msg_t   app_inquiry_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_sd_msg_t   app_sd_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_sec_msg_t   app_sec_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_conn_msg_t   app_conn_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
      } ros_msg&amp;lt;br&amp;gt;&lt;br /&gt;
   } app_msg_t;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first element of the union app_name_msg matches with the first enum value of DEVICE_NAME (discriminant within ros_hdr). The number and order of the discriminant values (app_opcodes_t) are the same as the union members.&lt;br /&gt;
&lt;br /&gt;
If the union within the message contains other unions (nested unions), the same rule would apply. The following example demonstrates app_sec_msg_t within ros_msg:&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef enum&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
        DISCOVERABLE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        CONNECTABLE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        SEC_AUTHORIZE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        SEC_AUTHENTICATE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        SEC_BOND_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
   } app_prim_sec_t;&amp;lt;br&amp;gt;&lt;br /&gt;
 typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
    app_prim_sec_t sec_msg_rsp;&amp;lt;br&amp;gt;&lt;br /&gt;
 union&amp;lt;br&amp;gt;&lt;br /&gt;
 { &amp;lt;br&amp;gt;&lt;br /&gt;
        discoverable_mode   discoverable_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        connectable_info_t   connectable_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        authorize_info_t   authorize_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        authenticate_info_t   authenticate_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        user_info_input_t   user_input_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        bond_info_t   bond_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        } sec_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
 } app_sec_msg_t;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above examples have the same number of discriminant values and union members. There is a one-to-one correlation between discriminant and union member. Having a discriminant for each union within nested unions decouples the unions and makes it more scalable and easier to maintain. The unions become independent of each other and can easily be extended.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_does_STRIDE_know_about_my_APIs_and_messaging_interfaces%3F&amp;diff=3560</id>
		<title>Studio:How does STRIDE know about my APIs and messaging interfaces?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_does_STRIDE_know_about_my_APIs_and_messaging_interfaces%3F&amp;diff=3560"/>
		<updated>2008-02-05T21:56:20Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE learns about APIs and messaging interfaces through the header files of embedded applications. To clarify ambiguities in complex interfaces, developers add pragma statements (SCL) to further specify the characteristics of interfaces and data types. STRIDE compiles through these header files and builds an XML database of the application interface signatures.  These application interfaces are now remotely available to the developer through STRIDE.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_can_I_tell_which_version_of_a_workspace_is_used_when_connected_to_the_target_at_runtime%3F&amp;diff=3555</id>
		<title>Studio:How can I tell which version of a workspace is used when connected to the target at runtime?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_can_I_tell_which_version_of_a_workspace_is_used_when_connected_to_the_target_at_runtime%3F&amp;diff=3555"/>
		<updated>2008-02-05T21:45:40Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When working with multiple targets, you may want to determine which version of a workspace is being used at runtime. To determine the target to which you are connected, add a helper function to the Intercept Module which can return something from the target (e.g., a string whose value is a target compile-time setting) that will tell the script the kind of target to which it is connected.&lt;br /&gt;
&lt;br /&gt;
You can also add a preprocessor define with a version number as part of the workspace build (not the target build). The define is not used for compilation. A script will check which preprocessor define is set and act accordingly.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Sending_and_receiving_broadcast_messages_in_the_Runtime&amp;diff=3554</id>
		<title>Studio:Sending and receiving broadcast messages in the Runtime</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Sending_and_receiving_broadcast_messages_in_the_Runtime&amp;diff=3554"/>
		<updated>2008-02-05T21:45:22Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If broadcast messages are being sent from the target to the host (i.e., there are no subscribers on the target), the data must be marshalled up to the host. However, when both the broadcaster (owner) and a receiver (user) are on the target, it is more efficient to specify srST_RSP_PTR since only a pointer to the message is moved internally. &lt;br /&gt;
&lt;br /&gt;
By contrast, if srST_RSP_VAL is specified, the entire message is copied before being sent.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Handling_non-standard_or_unsupported_keywords&amp;diff=3552</id>
		<title>Handling non-standard or unsupported keywords</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Handling_non-standard_or_unsupported_keywords&amp;diff=3552"/>
		<updated>2008-02-05T21:42:52Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For example if the &amp;lt;tt&amp;gt;__inline__&amp;lt;/tt&amp;gt; keyword is missing or unsupported, you can work around it by adding &amp;lt;tt&amp;gt;&#039;__inline__=&#039;&amp;lt;/tt&amp;gt; to the workspace definitions.&lt;br /&gt;
&lt;br /&gt;
[[Category:Troubleshooting]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_do_I_work_around_variable_arguments_for_stubs%3F&amp;diff=3551</id>
		<title>Studio:How do I work around variable arguments for stubs?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_do_I_work_around_variable_arguments_for_stubs%3F&amp;diff=3551"/>
		<updated>2008-02-05T21:34:04Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE does not directly support variable argument lists; however, it is possible to call interfaces with variable arguments as stubs. Currently there is no workaround for proxies or dynamic delegates.&amp;lt;br&amp;gt;&lt;br /&gt;
Interfaces with variable arguments can be wrapped using helper functions in the SCL file. The wrapper function depends on the number of variable arguments and the interface.&amp;lt;br&amp;gt;&lt;br /&gt;
For example, the UNIX system call &amp;quot;open&amp;quot; is defined as:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;extern int open (const char *__file, int __oflag, ...);&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In most cases, the variable argument is NULL; however, when creating a file, the file permission can be specified as an optional argument. In this case, it is simplest to call a wrapper function to the SCL file which has 3 arguments (the 3rd one being the mode). The wrapper function would be defined as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static int scl_file_open (const char *file, int oflag, mode_t mode)&amp;lt;br&amp;gt;&lt;br /&gt;
     {&amp;lt;br&amp;gt;&lt;br /&gt;
       return open(file, oflag, mode);&amp;lt;br&amp;gt;&lt;br /&gt;
     }&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The wrapper function calls the open interface with the three arguments. The SCL pragmas would be applied to scl_file_open:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(scl_file_open)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_string(scl_file_open.file, MAX_FILE_NAME_LENGTH)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Having a wrapper function for each possible variable argument could require a number of different wrapper functions if the variable argument can be of different types (e.g., a pointer to different structures), depending on the mandatory arguments. In this case, it would be easier to define the variable arguments as a union of all possible types. The UNIX system call &amp;quot;ioctl&amp;quot; could be an example of such an interface:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;extern int ioctl (int __fd, unsigned long int __request, ...) ;&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In most cases the variable argument (if there is one) is a pointer to a structure. The structure depends on the request value. An ioctl request has encoded in it whether the argument is an &amp;quot;in&amp;quot; parameter or &amp;quot;out&amp;quot; parameter, and the size of the variable argument in bytes.&lt;br /&gt;
&lt;br /&gt;
Click [http://linux.about.com/library/cmd/blcmdl2_ioctl_list.htm?terms=config+h here] for a list of possible ioctl requests and the variable argument types. In this case, the variable argument could be wrapped by a union. The following example demonstrates a possible union definition in the SCL file:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef union&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
  struct termios* p_termios;             /* TCGETS, TCSETS, TCSETSW, TCSETSF, TIOCGLCKTRMIOS, TIOCSLCKTRMIOS */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct termio* p_termio;               /* TCGETA, TCSETA, TCSETAW, TCSETAF */&amp;lt;br&amp;gt;&lt;br /&gt;
  int data;                              /* TCSBRK, TCXONC, TCFLSH, TIOCSCTTY, TCSBRKP, TIOCSBRK, TIOCCBRK, TIOCMIWAIT, TIOCGICOUNT,                   &lt;br /&gt;
                                         IOCGHAYESESP, TIOCSHAYESESP    */&amp;lt;br&amp;gt;&lt;br /&gt;
  int* p_int;                            /* TIOCOUTQ, TIOCMGET, TIOCMBIS,TIOCMBIC, TIOCMSET, TIOCGSOFTCAR, TIOCSSOFTCAR, FIONREAD,  &lt;br /&gt;
                                         TIOCINQ, IOCPKT, FIONBIO, TIOCSETD, TIOCGETD, FIOASYNC, TIOCSERGWILD, TIOCSERSWILD, &lt;br /&gt;
                                         TIOCSERGETLSR, FIOQSIZE */&amp;lt;br&amp;gt;&lt;br /&gt;
  pid_t* p_pid;                          /* TIOCGPGRP, TIOCSPGRP, TIOCGSID */&amp;lt;br&amp;gt;&lt;br /&gt;
  char* p_char;                          /* TIOCSTI, TIOCLINUX */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct winsize* p_winsize;             /* TIOCGWINSZ, TIOCSWINSZ */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct serial_struct* p_serial_struct; /* TIOCGSERIAL, TIOCSSERIAL */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct async_struct* p_async_struct;   /* TIOCSERGSTRUCT */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct serial_multiport_struct* p_serial_mp;  /* TIOCSERGETMULTI, TIOCSERSETMULTI */&amp;lt;br&amp;gt;&lt;br /&gt;
                                                /* void: TIOCNXCL, TIOCCONS, TIOCNOTTY, FIONCLEX, FIOCLEX, TIOCSERCONFIG, TIOCEXCL,  */&lt;br /&gt;
  } scl_ioctl_u; &amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The wrapper function will take a pointer to the union as the third argument. Depending on the request, the variable argument can be an input or output pointer. The request argument (union discriminate) is passed by value and therefore is an input only.&lt;br /&gt;
&lt;br /&gt;
STRIDE does not support output pointers to unions without a discriminate value (or input only discriminate).&lt;br /&gt;
&lt;br /&gt;
To have a discriminate value in both the input and output direction, the request parameter has to be passed as a pointer to the wrapper function. When the request is passed as a pointer, the discriminate is available in both the input and output direction. The wrapper function is defined as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static int scl_ioctl (int fd, unsigned long int* request, scl_ioctl_u* args)&amp;lt;br&amp;gt;&lt;br /&gt;
     {&amp;lt;br&amp;gt;&lt;br /&gt;
      return ioctl(fd, *request, args-&amp;gt;p_int);&amp;lt;br&amp;gt;&lt;br /&gt;
     }&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we need to specify the interface and the union using SCL. The pragmas are:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(scl_ioctl)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(scl_ioctl.args, INOUT, PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(scl_ioctl.request, INOUT, PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_values(*(scl_ioctl.request), TCGETS, TCSETS, TCSETSW, \  &lt;br /&gt;
                    TCSETSF, TCGETA, TCSETA, TCSETAW, TCSETAF,  \&lt;br /&gt;
                    TCSBRK, TCXONC, TCFLSH, TIOCEXCL, TIOCNXCL, \&lt;br /&gt;
                    TIOCSCTTY, TIOCGPGRP, TIOCSPGRP, TIOCOUTQ,  \&lt;br /&gt;
                    TIOCSTI, TIOCGWINSZ, TIOCSWINSZ, TIOCMGET,  \&lt;br /&gt;
                    TIOCMBIS, TIOCMBIC, TIOCMSET, TIOCGSOFTCAR, \&lt;br /&gt;
                    TIOCSSOFTCAR, FIONREAD, TIOCINQ, TIOCLINUX, \&lt;br /&gt;
                    TIOCCONS, TIOCGSERIAL, TIOCSSERIAL, TIOCPKT,\&lt;br /&gt;
                    FIONBIO, TIOCNOTTY, TIOCSETD, TIOCGETD,     \&lt;br /&gt;
                    TCSBRKP, TIOCSBRK, TIOCCBRK,                \&lt;br /&gt;
                    TIOCGSID, FIONCLEX, FIOCLEX, FIOASYNC,      \&lt;br /&gt;
                    TIOCSERCONFIG, TIOCSERGWILD, TIOCSERSWILD,  \&lt;br /&gt;
                    TIOCGLCKTRMIOS, TIOCSLCKTRMIOS,             \&lt;br /&gt;
                    TIOCSERGSTRUCT, TIOCSERGETLSR,              \&lt;br /&gt;
                    TIOCSERGETMULTI, TIOCSERSETMULTI,           \&lt;br /&gt;
                    TIOCMIWAIT, TIOCGICOUNT, TIOCGHAYESESP,     \&lt;br /&gt;
                    TIOCSHAYESESP, FIOQSIZE);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union(*(scl_ioctl.args), *(scl_ioctl.request));&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_termios, TCGETS, TCSETS, TCSETSW, TCSETSF, TIOCGLCKTRMIOS, TIOCSLCKTRMIOS);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_termio, TCGETA, TCSETA, TCSETAW, TCSETAF);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), data, TCSBRK, TCXONC, TCFLSH, TIOCSCTTY, TCSBRKP, TIOCSBRK, TIOCCBRK, TIOCMIWAIT,  &lt;br /&gt;
 TIOCGICOUNT, TIOCGHAYESESP, TIOCSHAYESESP);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_int, TIOCOUTQ, TIOCMGET, TIOCMBIS,TIOCMBIC, TIOCMSET, TIOCGSOFTCAR, TIOCSSOFTCAR,         &lt;br /&gt;
 FIONREAD, TIOCPKT, FIONBIO, TIOCSETD, TIOCGETD, FIOASYNC, TIOCSERGWILD, TIOCSERSWILD, TIOCSERGETLSR, FIOQSIZE);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_pid, TIOCGPGRP, TIOCSPGRP, TIOCGSID);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_char, TIOCSTI, TIOCLINUX);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_winsize, TIOCGWINSZ, TIOCSWINSZ);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_serial_struct, TIOCGSERIAL, TIOCSSERIAL);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_async_struct, TIOCSERGSTRUCT);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_serial_mp, TIOCSERGETMULTI, TIOCSERSETMULTI);&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Understanding_SCL_conflicts&amp;diff=3550</id>
		<title>Studio:Understanding SCL conflicts</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Understanding_SCL_conflicts&amp;diff=3550"/>
		<updated>2008-02-05T21:33:49Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is a new class of conflicts reported by the compiler called SCL conflicts. These conflicts are caused when two or more top-level header files contain conflicting constant values or pragmatized types. These were silently ignored in previous versions of STRIDE.&lt;br /&gt;
&lt;br /&gt;
There are two types of SCL conflicts:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The value of an enumeration constant or numeric valued preprocessor macro is in conflict with the results of the compilation of two top-level header files. A warning will be issued indicating the name associated with the inconsistent values. The compilation will still be successful, as this is only a warning; however, the value for the constant stored in ascript.Constants() will be the string “ERROR_VALUE_CONFLICT” rather than either of the original conflicting numeric values. In previous versions of STRIDE, the second value was accepted by default.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A type, T, occurs in two different top-level header files and is structurally different in both. This structural difference can be caused by inconsistent or conflicting SCL pragmas applied to the type, or it can be caused by a C language difference between the types. This type of conflict is considered an error; therefore, the compilation fails and error message is returned.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example 1&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The following example uses two top-level header files, Header1.h and Header2.h.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Header1.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define A 1&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Header2.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define A 2&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
The compilation of workspace 1 (via Header1.h) will return a Merge Conflict warning for “A”. The compilation will still be successful; the value of “A” in ascript.Constants() will be the string “ERROR_VALUE_CONFLICT”.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example 2&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The following example uses two top-level header files, Header1.h and Header2.h, and one header file that is not a top-level header file, NotTopLevelHeader.h.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Header1.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include &amp;quot;NotTopLevelHeader.h&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr (S.p, OUT, PRIVATE);&amp;lt;br&amp;gt;&lt;br /&gt;
 int f (S s);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(f);&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&#039;&#039;Header2.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include &amp;quot;NotTopLevelHeader.h&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
 int g (S s);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(g);&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&#039;&#039;NotTopLevelHeader.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct S {int *p;} S;&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
As a result of the functions f() and g() having a different picture of the shared type S, the compilation fails and returns the following Merge Error:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;... \header1.h(0) : Error : Merge conflict -- Found conflicting destinations for scl_ptr(S.p, ... )&amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_does_the_STRIDE_compiler_handle_zero-length_arrays%3F&amp;diff=3549</id>
		<title>Studio:How does the STRIDE compiler handle zero-length arrays?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_does_the_STRIDE_compiler_handle_zero-length_arrays%3F&amp;diff=3549"/>
		<updated>2008-02-05T21:33:17Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Under option, the STRIDE compiler allows an stucture member array to be declared with zero length. This is most frequently used for the last member of a structure (although it may be used for any member). The declaration of a zero length array affects the structure in the following ways: &lt;br /&gt;
&lt;br /&gt;
1. The size of the structure will be adjusted upward, if necessary, so that it ends on a boundary suitable for a field of the declared array type. &lt;br /&gt;
&lt;br /&gt;
2. The offset of the first member following the zero length array declaration, if one exists, will be adjusted upward to a boundary suitable for a field of the declared array type if necessary. &lt;br /&gt;
&lt;br /&gt;
As an example, consider: &lt;br /&gt;
&lt;br /&gt;
  struct S {&lt;br /&gt;
     char i; &lt;br /&gt;
     int   ary[0];  &lt;br /&gt;
  }; &lt;br /&gt;
&lt;br /&gt;
Assuming that char is one byte in size and requires single-byte alignment and int has four byte size and four byte alignment, then &lt;br /&gt;
&lt;br /&gt;
   sizeof(struct S) == 4.&lt;br /&gt;
&lt;br /&gt;
If the zero length array had not been declared then &lt;br /&gt;
&lt;br /&gt;
   sizeof(struct S) == 1;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_do_I_apply_an_SCL_pragma_to_an_array%3F&amp;diff=3548</id>
		<title>Studio:How do I apply an SCL pragma to an array?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_do_I_apply_an_SCL_pragma_to_an_array%3F&amp;diff=3548"/>
		<updated>2008-02-05T21:33:00Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To apply an SCL pragma to an array, treat the array as if it was declared as a pointer and use pointer-type syntax. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef unsigned char BOOL;&amp;lt;br&amp;gt;&lt;br /&gt;
 #define TRUE 1&amp;lt;br&amp;gt;&lt;br /&gt;
 #define FALSE 0 &amp;lt;br&amp;gt;&lt;br /&gt;
 typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
   BOOL  list[5];&amp;lt;br&amp;gt;&lt;br /&gt;
   int   type;&amp;lt;br&amp;gt;&lt;br /&gt;
 } S_T;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 int foo(BOOL flag, S_T p);&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(foo)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_values(*S_T.list, TRUE, FALSE)&amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3546</id>
		<title>Category:SCL</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3546"/>
		<updated>2008-02-05T21:32:00Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Pointers===&lt;br /&gt;
* [[Can STRIDE marshal both data and pointers?]]&lt;br /&gt;
* [[Can an array be cast to a pointer?]]&lt;br /&gt;
* [[Casting and pointers]]&lt;br /&gt;
* [[Accessing target data while processing a proxy call]]&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
* [[How do I apply an SCL pragma to an array?]]&lt;br /&gt;
* [[Assigning array elements]]&lt;br /&gt;
* [[How does the STRIDE compiler handle zero-length arrays?]]&lt;br /&gt;
&lt;br /&gt;
===Callbacks===&lt;br /&gt;
* [[Accessing the return value of a function using scripting]]&lt;br /&gt;
* [[Are multiple callbacks possible?]]&lt;br /&gt;
* [[Callback functions in Perl scripts]]&lt;br /&gt;
&lt;br /&gt;
===Workarounds===&lt;br /&gt;
* [[How do I work around variable arguments for stubs?]]&lt;br /&gt;
* [[Understanding SCL conflicts]]&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
* [[Applying pragmas up and down type chains]]&lt;br /&gt;
&lt;br /&gt;
===Where should these topics go?===&lt;br /&gt;
* [[Advantages and disadvantages of &amp;quot;default&amp;quot; candidates]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Are_multiple_callbacks_possible%3F&amp;diff=3545</id>
		<title>Studio:Are multiple callbacks possible?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Are_multiple_callbacks_possible%3F&amp;diff=3545"/>
		<updated>2008-02-05T21:31:40Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Due to the single-threaded nature of most applications, once an off-target owner function is called, the owner may not call back into it. However, multiple callbacks may be done by using a short-term local timer which may continue processing after returning control back to the application and unblocking it. If callbacks are called from different threads it is possible that multiple callbacks are called at the same time.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3543</id>
		<title>Category:SCL</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3543"/>
		<updated>2008-02-05T21:20:55Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Pointers===&lt;br /&gt;
* [[Can STRIDE marshal both data and pointers?]]&lt;br /&gt;
* [[Can an array be cast to a pointer?]]&lt;br /&gt;
* [[Casting and pointers]]&lt;br /&gt;
* [[Accessing target data while processing a proxy call]]&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
* [[How do I apply an SCL pragma to an array?]]&lt;br /&gt;
* [[Assigning array elements]]&lt;br /&gt;
* [[How does the STRIDE compiler handle zero-length arrays?]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Callbacks===&lt;br /&gt;
* [[Accessing the return value of a function using scripting]]&lt;br /&gt;
* [[Are multiple callbacks possible?]]&lt;br /&gt;
* [[Callback functions in Perl scripts]]&lt;br /&gt;
&lt;br /&gt;
===Workarounds===&lt;br /&gt;
* [[How do I work around variable arguments for stubs?]]&lt;br /&gt;
* [[Understanding SCL conflicts]]&lt;br /&gt;
&lt;br /&gt;
===Unions===&lt;br /&gt;
* [[Applying pragmas up and down type chains]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Where should these topics go?===&lt;br /&gt;
* [[Advantages and disadvantages of &amp;quot;default&amp;quot; candidates]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Applying_pragmas_up_and_down_type_chains&amp;diff=3542</id>
		<title>Studio:Applying pragmas up and down type chains</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Applying_pragmas_up_and_down_type_chains&amp;diff=3542"/>
		<updated>2008-02-05T21:08:46Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When a type T is pragmatized, it also applies to any types that are defined in terms of T.&lt;br /&gt;
&lt;br /&gt;
In the following SCL, Example 1 demonstrates when the scl_union pragma has no effect on pS, S1, or pS1. This is by design. In order for the pragma to apply, it must be structured as shown in Example 2.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example 1&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct {&amp;lt;br&amp;gt;&lt;br /&gt;
 enum {A,B}  discrim;&amp;lt;br&amp;gt;&lt;br /&gt;
 union &amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
    int x;&amp;lt;br&amp;gt; &lt;br /&gt;
    float f; &amp;lt;br&amp;gt;&lt;br /&gt;
   } u;&amp;lt;br&amp;gt; &lt;br /&gt;
 } S, *pS, S1, *pS1; &amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union(S, u, discrim);  &amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example 2&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct {&amp;lt;br&amp;gt;&lt;br /&gt;
 enum {A,B}  discrim;&amp;lt;br&amp;gt;&lt;br /&gt;
 union&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
     int x; &amp;lt;br&amp;gt;&lt;br /&gt;
     float f; &amp;lt;br&amp;gt;&lt;br /&gt;
   } u;&amp;lt;br&amp;gt; &lt;br /&gt;
 } S;&amp;lt;br&amp;gt; &lt;br /&gt;
 typedef S* pS;  &amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union(S, u, discrim); &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Advantages_and_disadvantages_of_%22default%22_candidates&amp;diff=3541</id>
		<title>Studio:Advantages and disadvantages of &quot;default&quot; candidates</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Advantages_and_disadvantages_of_%22default%22_candidates&amp;diff=3541"/>
		<updated>2008-02-05T21:08:31Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following table describes the advantages and disadvantages associated with the &amp;quot;default&amp;quot; candidate method vs. the candidate method.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;, cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
! &lt;br /&gt;
&lt;br /&gt;
! &#039;&#039;&#039;&amp;quot;Default&amp;quot; candidate method&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
! &#039;&#039;&#039;Candidate method&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039;Define and pragmatize each function prototype&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
| Not needed.&lt;br /&gt;
&lt;br /&gt;
| Cumbersome if there are hundreds of candidate functions. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039;Code footprint of the generated code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
| Only the proxy/stub of the &amp;quot;default&amp;quot; candidate is generated; thus, the code footprint is much smaller. &lt;br /&gt;
&lt;br /&gt;
| The code footprint is dependent upon how many candidates are defined using the scl_ptr_flist() pragma, since a proxy/stub is generated for each candidate defined in the list.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039;Capturing of function callback command/response payloads via the trace module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
| Any function callback command/response payloads with the identical signature can be captured.  &lt;br /&gt;
&lt;br /&gt;
| Only those candidate functions defined in the scl_ptr_flist() pragma can be captured.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039; Visibility of function callbacks via the trace module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
| The function callback being called is unknown. All of the function callbacks with the identical signature will be displayed with the &amp;quot;default&amp;quot; candidate name and SMID. &lt;br /&gt;
&lt;br /&gt;
| All of the function callbacks being called are known, as long as the candidate functions were declared in the scl_ptr_flist() pragma.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
One disadvantage of using the shorthand method to define candidates in scl_ptr_flist(), as shown in Method 3 of the [[Working with &amp;quot;default&amp;quot; candidates]] topic, is that the function pointer prototypes are not defined by the user/customer, but rather by STRIDE. So, for example, if the user wants to create a proxy for foo2() with stub candidate functions C2 and &amp;quot;cand4&amp;quot; on the target, the generated IM code will give &amp;quot;undefined&amp;quot; compiler errors for &amp;quot;cand4&amp;quot;. The following procedure using the header file MyHeader.h (the file containing the SCL pragmas or function prototypes) resolves this issue:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#ifdef srIMON&amp;lt;br&amp;gt;&lt;br /&gt;
 void cand4(int x, char y);&amp;lt;br&amp;gt;&lt;br /&gt;
 #endif &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The use of the srIMON preprocessor directive allows the SDAC to compile the file without any name conflicts for &amp;quot;cand4&amp;quot;, since these are already defined within STRIDE. It also allows the generated IM code to compile successfully.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyFunctions.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyFunctions.c is an example of a user-created file containing the actual code for the candidate &amp;quot;cand4&amp;quot;:&lt;br /&gt;
 &amp;lt;tt&amp;gt;void cand4(int x, char y)&amp;lt;br&amp;gt;&lt;br /&gt;
 { &amp;lt;br&amp;gt;&lt;br /&gt;
 } &amp;lt;br&amp;gt; &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyTest.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyTest.c is an example of a user-created file containing a test thread that makes the call to foo2() with the appropriate function pointer callback:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include “MyHeader.h”&amp;lt;br&amp;gt;&lt;br /&gt;
 FPtr funcPtr;&amp;lt;br&amp;gt;&lt;br /&gt;
 // set to cand4&amp;lt;br&amp;gt;&lt;br /&gt;
 funcPtr = cand4;&amp;lt;br&amp;gt;&lt;br /&gt;
 foo2(&amp;amp;funcPtr);&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In some instances, the candidates on the target are not known to the implementer of foo2() and the candidates may be static, so the above solution isn’t applicable. Using the “default” candidate mechanism is the perfect solution to this problem. The following example demonstrates how to do this (refer to Method 3 above):&lt;br /&gt;
&lt;br /&gt;
In MyHeader.h (the file that contains the SCL pragma’s or the function prototypes), replace the following:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_ptr_flist(*foo2.pFPtr, “cand4”, C2)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_ptr_flist(*foo2.pFPtr, “default_cand”) // default candidate&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyFunctions.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyFunctions.c is an example of a user-created file containing the actual code for the candidates (unknown_cand1, unknown_cand2):&lt;br /&gt;
 &amp;lt;tt&amp;gt;static void unknown_cand1(int x, char y)&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;br&amp;gt;&lt;br /&gt;
 static void unknown_cand2(int x, char y)&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyTest.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyTest.c is an example of a user-created file containing a test thread that makes the call to foo2() with the appropriate function pointer callback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include “MyHeader.h”&amp;lt;br&amp;gt;&lt;br /&gt;
 FPtr funcPtr;&amp;lt;br&amp;gt;&lt;br /&gt;
 // set to unknown_cand1&amp;lt;br&amp;gt;&lt;br /&gt;
 funcPtr = unknown_cand1;&amp;lt;br&amp;gt;&lt;br /&gt;
 foo2(&amp;amp;funcPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 // set to unknown_cand2&amp;lt;br&amp;gt;&lt;br /&gt;
 funcPtr = unknown_cand2;&amp;lt;br&amp;gt;&lt;br /&gt;
 foo2(&amp;amp;funcPtr);&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Accessing_target_data_while_processing_a_proxy_call&amp;diff=3540</id>
		<title>Studio:Accessing target data while processing a proxy call</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Accessing_target_data_while_processing_a_proxy_call&amp;diff=3540"/>
		<updated>2008-02-05T20:48:08Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In some cases, void pointers are passed into proxy functions calls, or the passed structures are so complex that they cannot completely be described for STRIDE. In these cases, the proxy (e.g., a script) might have to access certain data on the target to be able to validate the functionality of the call. For example, this might be required with an interface that writes structured data to a file:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;int write(const void *buffer, int element_size, int count)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
STRIDE needs to know the data structure in order to correctly marshal the data across platforms. The element size itself is not enough information for STRIDE. The buffer pointer could be typecast to a byte pointer; however, in this case the number of elements would be based on element size and count. STRIDE supports sized pointers, as long as the size is a single field and not the combination of multiple fields.&lt;br /&gt;
&lt;br /&gt;
How can an interface like this be easily dealt with in STRIDE if we plan on testing an application which uses this interface, but the library which implements the functionality is not yet available?&lt;br /&gt;
&lt;br /&gt;
First of all, the assumption is the actual structure is of no interest. We simply want to test the ability to write to a stream and later read from it, and verify we get the same data back. In this case, we can leave the buffer pointer as a void pointer and just pass the void pointer to STRIDE. Once in the proxy function, we need a way to retrieve the actual data at this pointer address from the target; this can be done with a helper function which reads a number of bytes from a certain memory address and passes it back to STRIDE. A simple helper function in the .h file perform this function:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static void SCL_get_num_bytes(void *ptr, unsigned char* data, int num_bytes)&lt;br /&gt;
 {&lt;br /&gt;
     memcpy(data, ptr, num_bytes);&lt;br /&gt;
 }&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An important note is that the data has to be valid when the helper function is called. In the case of a proxy call, the pointer should certainly be valid until the function returns. The proxy script is as follows:&lt;br /&gt;
    write.owner.register event = ascript.WaitForEvent(); &lt;br /&gt;
    if (event = write)&lt;br /&gt;
    {&lt;br /&gt;
       /* Copy the buffer pointer from the proxy call */&lt;br /&gt;
       scl_get_num_bytes.ParameterList.num_bytes = write.ParameterList.element_size *write.ParameterList.count;    &lt;br /&gt;
      &lt;br /&gt;
       /* Call the helper function to retrieve the data */ &lt;br /&gt;
       scl_get_num_bytes.Call();&lt;br /&gt;
      &lt;br /&gt;
       /* Process the data */ &lt;br /&gt;
       get_num_bytes.User.OutPointers.data ...     ...     &lt;br /&gt;
       &lt;br /&gt;
       write.Return();  &lt;br /&gt;
       /* return from the proxy function call */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The same can be done for the read function. Once the read proxy is called, a helper function can be called to copy the actual data in place. The read interface is as follows:&lt;br /&gt;
&lt;br /&gt;
   int read(void *buffer, int element_size, int count);&lt;br /&gt;
   static void SCL_set_num_bytes(void *ptr, unsigned char* data, int num_bytes)&lt;br /&gt;
   {&lt;br /&gt;
     memcpy(ptr, data, num_bytes);&lt;br /&gt;
   }&lt;br /&gt;
   read.owner.register event = ascript.WaitForEvent();&lt;br /&gt;
   if (event = read)&lt;br /&gt;
   {&lt;br /&gt;
     /* set the data to be read */&lt;br /&gt;
     set_num_bytes.User.ParameterList.data = ...     ...   &lt;br /&gt;
      &lt;br /&gt;
     /* copy the buffer pointer from the proxy call */ &lt;br /&gt;
     scl_set_num_bytes.ParameterList.ptr = read.ParameterList.buffer;&lt;br /&gt;
     &lt;br /&gt;
     /* calculate the number of bytes */     &lt;br /&gt;
     scl_set_num_bytes.ParameterList.num_bytes = read.ParameterList.element_size *read.ParameterList.count;  &lt;br /&gt;
     &lt;br /&gt;
     /* Call the helper function to retrieve the data */     &lt;br /&gt;
     scl_set_num_bytes.Call();     &lt;br /&gt;
     &lt;br /&gt;
     /* Process the data */     &lt;br /&gt;
     read.Return();  /* return from the proxy function call */&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3539</id>
		<title>Category:SCL</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3539"/>
		<updated>2008-02-05T20:47:57Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Pointers===&lt;br /&gt;
* [[Can STRIDE marshal both data and pointers?]]&lt;br /&gt;
* [[Can an array be cast to a pointer?]]&lt;br /&gt;
* [[Casting and pointers]]&lt;br /&gt;
* [[Accessing target data while processing a proxy call]]&lt;br /&gt;
&lt;br /&gt;
===Callbacks===&lt;br /&gt;
* [[Accessing the return value of a function using scripting]]&lt;br /&gt;
* [[Are multiple callbacks possible?]]&lt;br /&gt;
* [[Callback functions in Perl scripts]]&lt;br /&gt;
&lt;br /&gt;
===Workarounds===&lt;br /&gt;
* [[How do I work around variable arguments for stubs?]]&lt;br /&gt;
* [[Understanding SCL conflicts]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Casting_and_pointers&amp;diff=3536</id>
		<title>Studio:Casting and pointers</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Casting_and_pointers&amp;diff=3536"/>
		<updated>2008-02-05T18:50:38Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A cast must be applied to a pointer before anything else. In other words, you must apply scl_cast before scl_ptr, as illustrated by the following example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(GetUnicodeName)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_cast (GetUnicodeName, name, unsigned short*)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr (GetUnicodeName, name,  OUT,  PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_string (GetUnicodeName, name, 100)&amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Can_an_array_be_cast_to_a_pointer%3F&amp;diff=3530</id>
		<title>Studio:Can an array be cast to a pointer?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Can_an_array_be_cast_to_a_pointer%3F&amp;diff=3530"/>
		<updated>2008-02-05T18:04:38Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No. You cannot cast an array to a pointer type. Because there are subtle differences between them, they are not always interchangeable in SCL like they are in C.&lt;br /&gt;
&lt;br /&gt;
Instead of using the following:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;INT vr_get_foo(INT entry, INT index, file_table_t * out_buffer)&amp;lt;br&amp;gt;&lt;br /&gt;
 typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
     register ringer_types_t ringer_type;&amp;lt;br&amp;gt;&lt;br /&gt;
     BYTE alias_filename[(MAX_RINGER_ALIAS_NAME_LEN+1) *2];&amp;lt;br&amp;gt;&lt;br /&gt;
     UINT16 pad;&amp;lt;br&amp;gt;&lt;br /&gt;
 }ringer_file_table_t;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(v_get_mmedia_ringer)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(vr_get_mmedia_ringer, out_buffer, OUT, PRIVATE)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this SCL instead:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(vr_get_mmedia_ringer)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(vr_get_get_mmedia_ringer, out_buffer, OUT, PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_string(ringer_file_table_t, alias_filename, (MAX_RINGER_ALIAS_NAME_LEN+1) * 2)&amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Can_STRIDE_marshal_both_data_and_pointers%3F&amp;diff=3529</id>
		<title>Studio:Can STRIDE marshal both data and pointers?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Can_STRIDE_marshal_both_data_and_pointers%3F&amp;diff=3529"/>
		<updated>2008-02-05T17:54:11Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE does not marshal both the pointer value and the data. You have to pick one of the two. If a pointer is defined as void or the scl_ptr_opaque pragma is applied the pointer value is marshaled otherwise the data the pointer points to is marshaled. Opaque pointers can be passed to other functions or helper function to retrieve the data to which it points.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3528</id>
		<title>Category:SCL</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3528"/>
		<updated>2008-02-05T17:53:44Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Pointers===&lt;br /&gt;
* [[Can STRIDE marshal both data and pointers?]]&lt;br /&gt;
* [[Can an array be cast to a pointer?]]&lt;br /&gt;
* [[Casting and pointers]]&lt;br /&gt;
&lt;br /&gt;
===Callbacks===&lt;br /&gt;
* [[Accessing the return value of a function using scripting]]&lt;br /&gt;
* [[Are multiple callbacks possible?]]&lt;br /&gt;
* [[Callback functions in Perl scripts]]&lt;br /&gt;
&lt;br /&gt;
===Workarounds===&lt;br /&gt;
* [[How do I work around variable arguments for stubs?]]&lt;br /&gt;
* [[Understanding SCL conflicts]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3525</id>
		<title>Category:SCL</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Category:SCL&amp;diff=3525"/>
		<updated>2008-02-05T17:50:23Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Pointers===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Callbacks===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Workarounds===&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Working_with_%22default%22_candidates&amp;diff=3507</id>
		<title>Studio:Working with &quot;default&quot; candidates</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Working_with_%22default%22_candidates&amp;diff=3507"/>
		<updated>2008-02-04T23:48:27Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;scl_ptr_flist() serves as a &amp;quot;shorthand&amp;quot; method of declaring a &amp;quot;default&amp;quot; candidate.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: When using scl_ptr_flist() to define candidates, the function pointer prototypes are defined internally within STRIDE, rather than by the user. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;// function pointer typedef&amp;lt;br&amp;gt;&lt;br /&gt;
 typedef void (*FPtr) (int, char);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo(FPtr *pFPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo1(FPtr *pFPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo2(FPtr *pFPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 void foo3(FPtr *pFPtr);&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 // candidate prototypes &amp;lt;br&amp;gt;&lt;br /&gt;
 void C1(int x, char y);&amp;lt;br&amp;gt;&lt;br /&gt;
 void C2(int x, char y);&amp;lt;br&amp;gt;&lt;br /&gt;
 void C3(int x, char y);&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 // pragmatize candidate prototypes&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(C1)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(C2)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(C3)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to declare a &amp;quot;default&amp;quot; candidate using scl_ptr_flist()&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
There are several methods of declaring a &amp;quot;default&amp;quot; candidate using scl_ptr_flist(). Each method is explained below.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 1: Candidate list declaration using predefined function prototypes&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_flist(*foo.pFPtr, C1, C2, C3)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The candidates&#039; (C1, C2, C3) prototypes are defined and pragmatized, and proxies/stubs will be generated. In the parent function (the function that contains the function pointer PFptr) will use a for loop to search through the static table to bind the function pointer with the SMID or vice versa. The command and response payloads of the candidate functions (C1, C2, C3) can be captured via tracing.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 2: Candidate list declaration using shorthand method&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo1)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_flist(*foo1.pFPtr, &amp;quot;cand1&amp;quot;)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Default&amp;quot; proxies/stubs will be generated for the name in quotes in scl_ptr_flist() &amp;quot;cand1&amp;quot; in the example above. The command and response payloads of the candidate functions (e.g., &amp;quot;cand1&amp;quot;) can be captured via tracing.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 3: Candidate list declaration using combination of predefined functions and shorthand method&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo2)&lt;br /&gt;
 #pragma scl_ptr_flist(*foo2.pFPtr, &amp;quot;cand4&amp;quot;, C2)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The candidate &amp;quot;cand4&amp;quot; is interpreted by STRIDE as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt; void cand4(int p1, char p2);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(cand4)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Default&amp;quot; proxies/stubs will be generated for the name in quotes in scl_ptr_flist() &amp;quot;cand4&amp;quot; in the example above. The command and response payloads of the candidate functions (e.g., &amp;quot;cand4&amp;quot;) can be captured via tracing.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Method 4: &amp;quot;Default&amp;quot; candidate declaration&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(foo3)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_flist(*foo3.pFPtr, &amp;quot;def_cand&amp;quot;)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The candidate &amp;quot;def_cand&amp;quot; is interpreted by STRIDE as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;void def_cand(int p1, char p2);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(def_cand)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;default&amp;quot; proxy/stub will be generated for def_cand. The parent function will not use a for loop and the proxy will replace the existing function pointer in the table with the passed-in function pointer. The command and response payloads of any function prototype with the identical signature to def_cand can be captured via tracing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Using_printf&amp;diff=3506</id>
		<title>Studio:Using printf</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Using_printf&amp;diff=3506"/>
		<updated>2008-02-04T23:46:09Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In some cases, printf is a quick and easy way to add debug information to your code. When using STRIDE, it is helpful to have the printf output redirected to the trace view window, so that the printf output is in sequence with all the function calls, messages, and trace points. Having printf output sent to the trace views not only consolidates all the debug information into one place — the trace view — it also helps to understand the sequence of events.&lt;br /&gt;
&lt;br /&gt;
STRIDE provides a simple runtime command, srTraceStr, which sends strings to the trace window; however, replacing printf statements with srTraceStr in the source code can require a great deal of effort, which may not be worth it. A much simpler option is to use a macro definition to globally replace printf with srTraceStr. In addition, srTraceStr and printf&#039;s argument lists do not match exactly; therefore, parameter mapping is required. srTraceStr&#039;s syntax is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;srEXPORT srWORD srSTDCALL srTraceStr( srWORD      wSTID,&lt;br /&gt;
                                       srCHAR      *szString,&lt;br /&gt;
                                       srLevel_e   eLevel );&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
szString is the string to be displayed in the trace view. In addition, srTraceStr contains a filtering level for the host trace view. Since printf does not offer any level of trace view filtering, it can be mapped to a single level. In most cases, level 0 is appropriate since there is no need to filter printf statements; usually you want to see them, as they are generally there for a reason.&lt;br /&gt;
&lt;br /&gt;
srTraceStr&#039;s other parameter, wSTID, is a bit more complicated. A STID has to be created before srTraceStr can be called. The following two options are available:&lt;br /&gt;
*A STID specific to the printf tracing could be created in the target initialization code. In other words, the “STRIDE printf” would have its own STID, allowing it to be easily filtered out in the trace view if required.&lt;br /&gt;
*Alternately, the STID used for the intercept module could be reused. Since the scope of the “IM STID” is limited to the xxxIM.c file, the “STRIDE printf” would have to be part of this file. The intercept module is automatically generated, and therefore should not be modified; however, the example below demonstrates how the “IM STID” can be reused without having to modify the automatically-generated intercept module code.&lt;br /&gt;
&lt;br /&gt;
The following macro replaces printf with a function called stride_printf :&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define printf stride_printf&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we have to implement the stride_printf function. Since we replaced printf,we have to address variable arguments. The following example demonstrates a possible implementation:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static __inline srWORD stride_printf(char *s, ...)&lt;br /&gt;
 {&lt;br /&gt;
    srWORD ret;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_list args;&amp;lt;br&amp;gt;&lt;br /&gt;
    char str[MAX_STRIDE_PRINTF_SIZE];&amp;lt;br&amp;gt;&lt;br /&gt;
    va_start(args, s);&amp;lt;br&amp;gt;&lt;br /&gt;
    sprintf(str, s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
    ret = srTraceStr (wSTID, (srCHAR*) str, srLEVEL_0);&amp;lt;br&amp;gt;&lt;br /&gt;
    return ret;&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the intercept module STID (wSTID) was used.&lt;br /&gt;
&lt;br /&gt;
Now that we have made the change, the printf output will go to the STRIDE trace view — however, what if STRIDE is not being used but you still want to see the printf output? This can be done simply by adding a small function which allows switching between the normal printf and stride_printf; by exposing this interface in STRIDE, the output can be controlled regardless of whether or not you are using STRIDE. &lt;br /&gt;
 &amp;lt;tt&amp;gt;void stride_printf_set(stride_printf_flag_t flag)&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
   stride_printf_on = flag;&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the STRIDE printf function has to change slightly to add a “normal” printf:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;srWORD stride_printf(char *s, ...)&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
    srWORD ret = srOK;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_list args;&amp;lt;br&amp;gt;&lt;br /&gt;
    char str[MAX_STRIDE_PRINTF_SIZE];&amp;lt;br&amp;gt;&lt;br /&gt;
    va_start(args, s);&amp;lt;br&amp;gt;&lt;br /&gt;
    if ((!(stride_printf_on &amp;amp; STRIDE_PRINTF)) ||&amp;lt;br&amp;gt;&lt;br /&gt;
          (stride_printf_on &amp;amp; OS_PRINTF))&amp;lt;br&amp;gt;&lt;br /&gt;
    {&amp;lt;br&amp;gt;    &lt;br /&gt;
       printf(s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
    }&amp;lt;br&amp;gt;&lt;br /&gt;
    if (stride_printf_on &amp;amp; STRIDE_PRINTF)&amp;lt;br&amp;gt;&lt;br /&gt;
    {&amp;lt;br&amp;gt;&lt;br /&gt;
       sprintf(str, s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
       ret = srTraceStr (wSTID, (srCHAR*) str, srLEVEL_0);&amp;lt;br&amp;gt;&lt;br /&gt;
    }   &amp;lt;br&amp;gt;&lt;br /&gt;
    return ret;&amp;lt;br&amp;gt;&lt;br /&gt;
   }&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sample header files&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Two header files are required in order to use printf to add debug information to your code: a header file which redefines printf to stride_printf, and a header file containing the stride_printf implementation as an inline function as well as the SCL pragmas for STRIDE.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Redefining printf to stride_printf&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
This header file should be included in one of the general include files, which in turn is included in all the source files to limit source code modifications.&lt;br /&gt;
  &amp;lt;tt&amp;gt;#ifndef STRIDE_PRINTF_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #define STRIDE_PRINTF_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  extern &amp;quot;C&amp;quot; {&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #define MAX_STRIDE_PRINTF_SIZE  255&amp;lt;br&amp;gt;&lt;br /&gt;
  #define OS_PRINTF                 1&amp;lt;br&amp;gt;&lt;br /&gt;
  #define STRIDE_PRINTF             2&amp;lt;br&amp;gt;&lt;br /&gt;
  extern srWORD stride_printf(char *s);&amp;lt;br&amp;gt;&lt;br /&gt;
  /* Redefine printf to stride_printf */&amp;lt;br&amp;gt;&lt;br /&gt;
  #define printf stride_printf&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif  /* STRIDE_PRINTF_H */&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Implementing stride_printf as an inline function and SCL pragmas&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The stride_printf_scl.h file is included in the STRIDE workspace. It contains the stride_printf implementation as an inline function as well as the SCL pragmas for STRIDE.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;tt&amp;gt;#ifndef STRIDE_PRINTF_SCL_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #define STRIDE_PRINTF_SCL_H&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  extern &amp;quot;C&amp;quot; {&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdarg.h&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  #include &amp;quot;stride_printf.h&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
  static unsigned char stride_printf_on = OS_PRINTF;&amp;lt;br&amp;gt;&lt;br /&gt;
  extern srWORD   wSTID;&amp;lt;br&amp;gt;&lt;br /&gt;
  static __inline void stride_printf_set(unsigned char flag)&amp;lt;br&amp;gt;&lt;br /&gt;
  {&amp;lt;br&amp;gt;&lt;br /&gt;
   stride_printf_on = flag;&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #undef printf&amp;lt;br&amp;gt;&lt;br /&gt;
  static __inline srWORD stride_printf(char *s, ...)&amp;lt;br&amp;gt;&lt;br /&gt;
  {&amp;lt;br&amp;gt;&lt;br /&gt;
    srWORD ret = srOK;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_list args;&amp;lt;br&amp;gt;&lt;br /&gt;
    va_start(args, s);&amp;lt;br&amp;gt;&lt;br /&gt;
    if ((!(stride_printf_on &amp;amp; STRIDE_PRINTF)) ||&amp;lt;br&amp;gt;&lt;br /&gt;
          (stride_printf_on &amp;amp; OS_PRINTF))&amp;lt;br&amp;gt;&lt;br /&gt;
    {    &amp;lt;br&amp;gt;&lt;br /&gt;
       printf(s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
    }&amp;lt;br&amp;gt;&lt;br /&gt;
    if (stride_printf_on &amp;amp; STRIDE_PRINTF)&amp;lt;br&amp;gt;&lt;br /&gt;
    {&amp;lt;br&amp;gt;&lt;br /&gt;
       char str[MAX_STRIDE_PRINTF_SIZE];&amp;lt;br&amp;gt;&lt;br /&gt;
       sprintf(str, s, args);&amp;lt;br&amp;gt;&lt;br /&gt;
       ret = srTraceStr (wSTID, (srCHAR*) str, srLEVEL_0);&amp;lt;br&amp;gt;&lt;br /&gt;
    }   &amp;lt;br&amp;gt;&lt;br /&gt;
    return ret;&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef _SCL&amp;lt;br&amp;gt;&lt;br /&gt;
  #pragma scl_function(stride_printf_set)&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #ifdef __cplusplus&amp;lt;br&amp;gt;&lt;br /&gt;
  }&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif&amp;lt;br&amp;gt;&lt;br /&gt;
  #endif  /* STRIDE_PRINTF_SCL_H */&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Understanding_SCL_conflicts&amp;diff=3505</id>
		<title>Studio:Understanding SCL conflicts</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Understanding_SCL_conflicts&amp;diff=3505"/>
		<updated>2008-02-04T23:45:51Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is a new class of conflicts reported by the compiler called SCL conflicts. These conflicts are caused when two or more top-level header files contain conflicting constant values or pragmatized types. These were silently ignored in previous versions of STRIDE.&lt;br /&gt;
&lt;br /&gt;
There are two types of SCL conflicts:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The value of an enumeration constant or numeric valued preprocessor macro is in conflict with the results of the compilation of two top-level header files. A warning will be issued indicating the name associated with the inconsistent values. The compilation will still be successful, as this is only a warning; however, the value for the constant stored in ascript.Constants() will be the string “ERROR_VALUE_CONFLICT” rather than either of the original conflicting numeric values. In previous versions of STRIDE, the second value was accepted by default.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;A type, T, occurs in two different top-level header files and is structurally different in both. This structural difference can be caused by inconsistent or conflicting SCL pragmas applied to the type, or it can be caused by a C language difference between the types. This type of conflict is considered an error; therefore, the compilation fails and error message is returned.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example 1&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The following example uses two top-level header files, Header1.h and Header2.h.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Header1.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define A 1&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Header2.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define A 2&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
The compilation of workspace 1 (via Header1.h) will return a Merge Conflict warning for “A”. The compilation will still be successful; the value of “A” in ascript.Constants() will be the string “ERROR_VALUE_CONFLICT”.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example 2&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The following example uses two top-level header files, Header1.h and Header2.h, and one header file that is not a top-level header file, NotTopLevelHeader.h.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Header1.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include &amp;quot;NotTopLevelHeader.h&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr (S.p, OUT, PRIVATE);&amp;lt;br&amp;gt;&lt;br /&gt;
 int f (S s);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(f);&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&#039;&#039;Header2.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include &amp;quot;NotTopLevelHeader.h&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
 int g (S s);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(g);&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&#039;&#039;NotTopLevelHeader.h&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct S {int *p;} S;&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
As a result of the functions f() and g() having a different picture of the shared type S, the compilation fails and returns the following Merge Error:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;... \header1.h(0) : Error : Merge conflict -- Found conflicting destinations for scl_ptr(S.p, ... )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Sending_and_receiving_broadcast_messages_in_the_Runtime&amp;diff=3504</id>
		<title>Studio:Sending and receiving broadcast messages in the Runtime</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Sending_and_receiving_broadcast_messages_in_the_Runtime&amp;diff=3504"/>
		<updated>2008-02-04T23:45:22Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If broadcast messages are being sent from the target to the host (i.e., there are no subscribers on the target), the data must be marshalled up to the host. However, when both the broadcaster (owner) and a receiver (user) are on the target, it is more efficient to specify srST_RSP_PTR since only a pointer to the message is moved internally. &lt;br /&gt;
&lt;br /&gt;
By contrast, if srST_RSP_VAL is specified, the entire message is copied before being sent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Handling_non-standard_or_unsupported_keywords&amp;diff=3503</id>
		<title>Handling non-standard or unsupported keywords</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Handling_non-standard_or_unsupported_keywords&amp;diff=3503"/>
		<updated>2008-02-04T23:45:06Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For example if the &amp;lt;tt&amp;gt;__inline__&amp;lt;/tt&amp;gt; keyword is missing or unsupported, you can work around it by adding &amp;lt;tt&amp;gt;&#039;__inline__=&#039;&amp;lt;/tt&amp;gt; to the workspace definitions.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_to_generate_a_preprocessor_(.i)_file_for_analysis&amp;diff=3502</id>
		<title>Studio:How to generate a preprocessor (.i) file for analysis</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_to_generate_a_preprocessor_(.i)_file_for_analysis&amp;diff=3502"/>
		<updated>2008-02-04T23:44:47Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Preprocessing individual files&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can run the preprocessor on one or more header files to generate .i files, which can then be used for analysis. To do this from within Studio, select one or more top-level header files, right-click, and choose &#039;&#039;&#039;Preprocess&#039;&#039;&#039;. &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: You will need to rename the file to have a .h extension.&lt;br /&gt;
&lt;br /&gt;
Only the selected files are compiled, and preprocessed (.i) files are generated for them. During the compilation, the workspace settings for #defines and include paths are in effect. Existing databases are not affected. &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The #include &amp;lt;stdarg.h&amp;gt; will require the workspace to have a valid pointer (usually to the Microsoft C includes directory).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_to_define_message_structures&amp;diff=3500</id>
		<title>Studio:How to define message structures</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_to_define_message_structures&amp;diff=3500"/>
		<updated>2008-02-04T23:41:54Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following rules make it easier to process unions and select the active member(s) within a union or nested unions, as well as making it easier to transfer data between tasks.&lt;br /&gt;
* Have a one-to-one correlation between disciminants and union members.&lt;br /&gt;
* The order of enums for discriminants matches with the order of members within the union.&lt;br /&gt;
* In the case of nested unions, each union should have its own discriminant.&lt;br /&gt;
* Use inline data instead of pointers.&lt;br /&gt;
&lt;br /&gt;
Below is an example:&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
    DEVICE_NAME,&amp;lt;br&amp;gt;&lt;br /&gt;
    INQUIRY,&amp;lt;br&amp;gt;&lt;br /&gt;
    SD,&amp;lt;br&amp;gt;&lt;br /&gt;
    SECURITY,&amp;lt;br&amp;gt;&lt;br /&gt;
    CONN, &amp;lt;br&amp;gt;&lt;br /&gt;
   } app_opcodes_t;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corresponding message structure is as follows:&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
    ros_hdr_t  ros_hdr;&amp;lt;br&amp;gt;&lt;br /&gt;
    vris_hdr_t  vris_hdr;&amp;lt;br&amp;gt;&lt;br /&gt;
    app_hdr_t  app_hdr;&amp;lt;br&amp;gt;&lt;br /&gt;
 union&amp;lt;br&amp;gt;&lt;br /&gt;
      { &amp;lt;br&amp;gt;&lt;br /&gt;
        app_name_msg_t   app_name_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_inquiry_msg_t   app_inquiry_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_sd_msg_t   app_sd_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_sec_msg_t   app_sec_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
        app_conn_msg_t   app_conn_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
      } ros_msg&amp;lt;br&amp;gt;&lt;br /&gt;
   } app_msg_t;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first element of the union app_name_msg matches with the first enum value of DEVICE_NAME (discriminant within ros_hdr). The number and order of the discriminant values (app_opcodes_t) are the same as the union members.&lt;br /&gt;
&lt;br /&gt;
If the union within the message contains other unions (nested unions), the same rule would apply. The following example demonstrates app_sec_msg_t within ros_msg:&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef enum&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
        DISCOVERABLE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        CONNECTABLE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        SEC_AUTHORIZE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        SEC_AUTHENTICATE_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
        SEC_BOND_CFM,&amp;lt;br&amp;gt;&lt;br /&gt;
   } app_prim_sec_t;&amp;lt;br&amp;gt;&lt;br /&gt;
 typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
    app_prim_sec_t sec_msg_rsp;&amp;lt;br&amp;gt;&lt;br /&gt;
 union&amp;lt;br&amp;gt;&lt;br /&gt;
 { &amp;lt;br&amp;gt;&lt;br /&gt;
        discoverable_mode   discoverable_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        connectable_info_t   connectable_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        authorize_info_t   authorize_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        authenticate_info_t   authenticate_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        user_info_input_t   user_input_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        bond_info_t   bond_info;&amp;lt;br&amp;gt;&lt;br /&gt;
        } sec_msg;&amp;lt;br&amp;gt;&lt;br /&gt;
 } app_sec_msg_t;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above examples have the same number of discriminant values and union members. There is a one-to-one correlation between discriminant and union member. Having a discriminant for each union within nested unions decouples the unions and makes it more scalable and easier to maintain. The unions become independent of each other and can easily be extended.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_does_the_STRIDE_compiler_handle_zero-length_arrays%3F&amp;diff=3497</id>
		<title>Studio:How does the STRIDE compiler handle zero-length arrays?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_does_the_STRIDE_compiler_handle_zero-length_arrays%3F&amp;diff=3497"/>
		<updated>2008-02-04T23:39:34Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Under option, the STRIDE compiler allows an stucture member array to be declared with zero length. This is most frequently used for the last member of a structure (although it may be used for any member). The declaration of a zero length array affects the structure in the following ways: &lt;br /&gt;
&lt;br /&gt;
1. The size of the structure will be adjusted upward, if necessary, so that it ends on a boundary suitable for a field of the declared array type. &lt;br /&gt;
&lt;br /&gt;
2. The offset of the first member following the zero length array declaration, if one exists, will be adjusted upward to a boundary suitable for a field of the declared array type if necessary. &lt;br /&gt;
&lt;br /&gt;
As an example, consider: &lt;br /&gt;
&lt;br /&gt;
  struct S {&lt;br /&gt;
     char i; &lt;br /&gt;
     int   ary[0];  &lt;br /&gt;
  }; &lt;br /&gt;
&lt;br /&gt;
Assuming that char is one byte in size and requires single-byte alignment and int has four byte size and four byte alignment, then &lt;br /&gt;
&lt;br /&gt;
   sizeof(struct S) == 4.&lt;br /&gt;
&lt;br /&gt;
If the zero length array had not been declared then &lt;br /&gt;
&lt;br /&gt;
   sizeof(struct S) == 1; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_does_STRIDE_know_about_my_APIs_and_messaging_interfaces%3F&amp;diff=3495</id>
		<title>Studio:How does STRIDE know about my APIs and messaging interfaces?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_does_STRIDE_know_about_my_APIs_and_messaging_interfaces%3F&amp;diff=3495"/>
		<updated>2008-02-04T23:39:18Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE learns about APIs and messaging interfaces through the header files of embedded applications. To clarify ambiguities in complex interfaces, developers add pragma statements (SCL) to further specify the characteristics of interfaces and data types. STRIDE compiles through these header files and builds an XML database of the application interface signatures.  These application interfaces are now remotely available to the developer through STRIDE.&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_do_I_work_around_variable_arguments_for_stubs%3F&amp;diff=3494</id>
		<title>Studio:How do I work around variable arguments for stubs?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_do_I_work_around_variable_arguments_for_stubs%3F&amp;diff=3494"/>
		<updated>2008-02-04T23:39:01Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE does not directly support variable argument lists; however, it is possible to call interfaces with variable arguments as stubs. Currently there is no workaround for proxies or dynamic delegates.&amp;lt;br&amp;gt;&lt;br /&gt;
Interfaces with variable arguments can be wrapped using helper functions in the SCL file. The wrapper function depends on the number of variable arguments and the interface.&amp;lt;br&amp;gt;&lt;br /&gt;
For example, the UNIX system call &amp;quot;open&amp;quot; is defined as:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;extern int open (const char *__file, int __oflag, ...);&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In most cases, the variable argument is NULL; however, when creating a file, the file permission can be specified as an optional argument. In this case, it is simplest to call a wrapper function to the SCL file which has 3 arguments (the 3rd one being the mode). The wrapper function would be defined as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static int scl_file_open (const char *file, int oflag, mode_t mode)&amp;lt;br&amp;gt;&lt;br /&gt;
     {&amp;lt;br&amp;gt;&lt;br /&gt;
       return open(file, oflag, mode);&amp;lt;br&amp;gt;&lt;br /&gt;
     }&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The wrapper function calls the open interface with the three arguments. The SCL pragmas would be applied to scl_file_open:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(scl_file_open)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_string(scl_file_open.file, MAX_FILE_NAME_LENGTH)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Having a wrapper function for each possible variable argument could require a number of different wrapper functions if the variable argument can be of different types (e.g., a pointer to different structures), depending on the mandatory arguments. In this case, it would be easier to define the variable arguments as a union of all possible types. The UNIX system call &amp;quot;ioctl&amp;quot; could be an example of such an interface:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;extern int ioctl (int __fd, unsigned long int __request, ...) ;&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In most cases the variable argument (if there is one) is a pointer to a structure. The structure depends on the request value. An ioctl request has encoded in it whether the argument is an &amp;quot;in&amp;quot; parameter or &amp;quot;out&amp;quot; parameter, and the size of the variable argument in bytes.&lt;br /&gt;
&lt;br /&gt;
Click [http://linux.about.com/library/cmd/blcmdl2_ioctl_list.htm?terms=config+h here] for a list of possible ioctl requests and the variable argument types. In this case, the variable argument could be wrapped by a union. The following example demonstrates a possible union definition in the SCL file:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef union&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
  struct termios* p_termios;             /* TCGETS, TCSETS, TCSETSW, TCSETSF, TIOCGLCKTRMIOS, TIOCSLCKTRMIOS */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct termio* p_termio;               /* TCGETA, TCSETA, TCSETAW, TCSETAF */&amp;lt;br&amp;gt;&lt;br /&gt;
  int data;                              /* TCSBRK, TCXONC, TCFLSH, TIOCSCTTY, TCSBRKP, TIOCSBRK, TIOCCBRK, TIOCMIWAIT, TIOCGICOUNT,                   &lt;br /&gt;
                                         IOCGHAYESESP, TIOCSHAYESESP    */&amp;lt;br&amp;gt;&lt;br /&gt;
  int* p_int;                            /* TIOCOUTQ, TIOCMGET, TIOCMBIS,TIOCMBIC, TIOCMSET, TIOCGSOFTCAR, TIOCSSOFTCAR, FIONREAD,  &lt;br /&gt;
                                         TIOCINQ, IOCPKT, FIONBIO, TIOCSETD, TIOCGETD, FIOASYNC, TIOCSERGWILD, TIOCSERSWILD, &lt;br /&gt;
                                         TIOCSERGETLSR, FIOQSIZE */&amp;lt;br&amp;gt;&lt;br /&gt;
  pid_t* p_pid;                          /* TIOCGPGRP, TIOCSPGRP, TIOCGSID */&amp;lt;br&amp;gt;&lt;br /&gt;
  char* p_char;                          /* TIOCSTI, TIOCLINUX */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct winsize* p_winsize;             /* TIOCGWINSZ, TIOCSWINSZ */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct serial_struct* p_serial_struct; /* TIOCGSERIAL, TIOCSSERIAL */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct async_struct* p_async_struct;   /* TIOCSERGSTRUCT */&amp;lt;br&amp;gt;&lt;br /&gt;
  struct serial_multiport_struct* p_serial_mp;  /* TIOCSERGETMULTI, TIOCSERSETMULTI */&amp;lt;br&amp;gt;&lt;br /&gt;
                                                /* void: TIOCNXCL, TIOCCONS, TIOCNOTTY, FIONCLEX, FIOCLEX, TIOCSERCONFIG, TIOCEXCL,  */&lt;br /&gt;
  } scl_ioctl_u; &amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The wrapper function will take a pointer to the union as the third argument. Depending on the request, the variable argument can be an input or output pointer. The request argument (union discriminate) is passed by value and therefore is an input only.&lt;br /&gt;
&lt;br /&gt;
STRIDE does not support output pointers to unions without a discriminate value (or input only discriminate).&lt;br /&gt;
&lt;br /&gt;
To have a discriminate value in both the input and output direction, the request parameter has to be passed as a pointer to the wrapper function. When the request is passed as a pointer, the discriminate is available in both the input and output direction. The wrapper function is defined as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static int scl_ioctl (int fd, unsigned long int* request, scl_ioctl_u* args)&amp;lt;br&amp;gt;&lt;br /&gt;
     {&amp;lt;br&amp;gt;&lt;br /&gt;
      return ioctl(fd, *request, args-&amp;gt;p_int);&amp;lt;br&amp;gt;&lt;br /&gt;
     }&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we need to specify the interface and the union using SCL. The pragmas are:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(scl_ioctl)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(scl_ioctl.args, INOUT, PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(scl_ioctl.request, INOUT, PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_values(*(scl_ioctl.request), TCGETS, TCSETS, TCSETSW, \  &lt;br /&gt;
                    TCSETSF, TCGETA, TCSETA, TCSETAW, TCSETAF,  \&lt;br /&gt;
                    TCSBRK, TCXONC, TCFLSH, TIOCEXCL, TIOCNXCL, \&lt;br /&gt;
                    TIOCSCTTY, TIOCGPGRP, TIOCSPGRP, TIOCOUTQ,  \&lt;br /&gt;
                    TIOCSTI, TIOCGWINSZ, TIOCSWINSZ, TIOCMGET,  \&lt;br /&gt;
                    TIOCMBIS, TIOCMBIC, TIOCMSET, TIOCGSOFTCAR, \&lt;br /&gt;
                    TIOCSSOFTCAR, FIONREAD, TIOCINQ, TIOCLINUX, \&lt;br /&gt;
                    TIOCCONS, TIOCGSERIAL, TIOCSSERIAL, TIOCPKT,\&lt;br /&gt;
                    FIONBIO, TIOCNOTTY, TIOCSETD, TIOCGETD,     \&lt;br /&gt;
                    TCSBRKP, TIOCSBRK, TIOCCBRK,                \&lt;br /&gt;
                    TIOCGSID, FIONCLEX, FIOCLEX, FIOASYNC,      \&lt;br /&gt;
                    TIOCSERCONFIG, TIOCSERGWILD, TIOCSERSWILD,  \&lt;br /&gt;
                    TIOCGLCKTRMIOS, TIOCSLCKTRMIOS,             \&lt;br /&gt;
                    TIOCSERGSTRUCT, TIOCSERGETLSR,              \&lt;br /&gt;
                    TIOCSERGETMULTI, TIOCSERSETMULTI,           \&lt;br /&gt;
                    TIOCMIWAIT, TIOCGICOUNT, TIOCGHAYESESP,     \&lt;br /&gt;
                    TIOCSHAYESESP, FIOQSIZE);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union(*(scl_ioctl.args), *(scl_ioctl.request));&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_termios, TCGETS, TCSETS, TCSETSW, TCSETSF, TIOCGLCKTRMIOS, TIOCSLCKTRMIOS);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_termio, TCGETA, TCSETA, TCSETAW, TCSETAF);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), data, TCSBRK, TCXONC, TCFLSH, TIOCSCTTY, TCSBRKP, TIOCSBRK, TIOCCBRK, TIOCMIWAIT,  &lt;br /&gt;
 TIOCGICOUNT, TIOCGHAYESESP, TIOCSHAYESESP);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_int, TIOCOUTQ, TIOCMGET, TIOCMBIS,TIOCMBIC, TIOCMSET, TIOCGSOFTCAR, TIOCSSOFTCAR,         &lt;br /&gt;
 FIONREAD, TIOCPKT, FIONBIO, TIOCSETD, TIOCGETD, FIOASYNC, TIOCSERGWILD, TIOCSERSWILD, TIOCSERGETLSR, FIOQSIZE);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_pid, TIOCGPGRP, TIOCSPGRP, TIOCGSID);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_char, TIOCSTI, TIOCLINUX);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_winsize, TIOCGWINSZ, TIOCSWINSZ);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_serial_struct, TIOCGSERIAL, TIOCSSERIAL);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_async_struct, TIOCSERGSTRUCT);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union_activate(*(scl_ioctl.args), p_serial_mp, TIOCSERGETMULTI, TIOCSERSETMULTI);&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_do_I_apply_an_SCL_pragma_to_an_array%3F&amp;diff=3493</id>
		<title>Studio:How do I apply an SCL pragma to an array?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_do_I_apply_an_SCL_pragma_to_an_array%3F&amp;diff=3493"/>
		<updated>2008-02-04T23:38:23Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To apply an SCL pragma to an array, treat the array as if it was declared as a pointer and use pointer-type syntax. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef unsigned char BOOL;&amp;lt;br&amp;gt;&lt;br /&gt;
 #define TRUE 1&amp;lt;br&amp;gt;&lt;br /&gt;
 #define FALSE 0 &amp;lt;br&amp;gt;&lt;br /&gt;
 typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
   BOOL  list[5];&amp;lt;br&amp;gt;&lt;br /&gt;
   int   type;&amp;lt;br&amp;gt;&lt;br /&gt;
 } S_T;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 int foo(BOOL flag, S_T p);&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(foo)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_values(*S_T.list, TRUE, FALSE)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_do_I_access_global_variables%3F&amp;diff=3492</id>
		<title>Studio:How do I access global variables?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_do_I_access_global_variables%3F&amp;diff=3492"/>
		<updated>2008-02-04T23:38:06Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE allows you to call functions and send messages on the target, which is in most cases all you need for validation. However, in some cases it might be necessary to read or modify global variables or certain memory locations. If there are API functions available to access the global variables or read memory, those APIs could be exposed to STRIDE and used. If no such API calls are available, they can be added; this requires changes to the target code. Although STRIDE doesn’t directly support accessing target memory with simple helper functions, you can easily access target information without changing the target code by adding code to a header file containing SCL pragmas.&lt;br /&gt;
&lt;br /&gt;
This header file would then be included in the STRIDE workspace, and therefore included in the intercept module. It would not be required to include the header file in any of the customer target code, nor would modifications to the customer code be required. Since the function is known to the intercept module and the intercept module is the only one calling the function, it could be static and therefore have no impact on the rest of the code. The following demonstrates a header file which is included in the STRIDE workspace and subsequently in the intercept module; the function is defined as static, since its scope is limited to the intercept module.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example: Reading a number of bytes from the target&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;static  void SCL_get_num_bytes ( void *ptr, unsigned char* data, int num_bytes)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;{ &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;    memcpy ( data, ptr, num_bytes ); &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;} &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reading and writing global data&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Another application is to read and write global data. For example, we could have a global state variable. Either the header file which defines the global state variable could be included, or an external definition could be added to the header file. The first option is preferred; in some cases the global state variable definition could be in a .c file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example: STRIDE header file&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/* extern definition for global */&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;extern int global_state&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/* helper function to set the state */&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;static void SCL_set_state(int state)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; { &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; global_state = state; &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; } &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; /* helper function to get (read) the state */ &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; static  int SCL_get_state(void) &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; { &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; return global_state;&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt; } &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:How_can_I_tell_which_version_of_a_workspace_is_used_when_connected_to_the_target_at_runtime%3F&amp;diff=3491</id>
		<title>Studio:How can I tell which version of a workspace is used when connected to the target at runtime?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:How_can_I_tell_which_version_of_a_workspace_is_used_when_connected_to_the_target_at_runtime%3F&amp;diff=3491"/>
		<updated>2008-02-04T23:37:40Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When working with multiple targets, you may want to determine which version of a workspace is being used at runtime. To determine the target to which you are connected, add a helper function to the Intercept Module which can return something from the target (e.g., a string whose value is a target compile-time setting) that will tell the script the kind of target to which it is connected.&lt;br /&gt;
&lt;br /&gt;
You can also add a preprocessor define with a version number as part of the workspace build (not the target build). The define is not used for compilation. A script will check which preprocessor define is set and act accordingly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Delegating_ISHELL_SendEvent&amp;diff=3489</id>
		<title>Studio:Delegating ISHELL SendEvent</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Delegating_ISHELL_SendEvent&amp;diff=3489"/>
		<updated>2008-02-04T23:32:15Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When trying to dynamically intercept a call for the application under test, intercepting only the call/method of interest was difficult when delegating the IShell Virtual Table, as it allows all methods to be intercepted for all callers.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delegating the user&#039;s call to the IShell helper macro ISHELL_SendEvent is a better method. ISHELL_SendEvent is defined in AEEShell.h as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#define ISHELL_SendEvent(p,cls,ec,wp,dw)&amp;lt;br&amp;gt;&lt;br /&gt;
 GET_PVTBL(p,IShell)-&amp;gt;SendEvent(p,0,cls,ec,wp,dw)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This requires a small amount of instrumentation to the calling application, essentially to define the Group ID and include IM.h. You must also complete the following steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ensure that the calling application is using the helper macro to call the Send event.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add the following code to the AEEShell.h file instead of the #ifdef _SCL conditional block:&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#undef ISHELL_SendEvent&amp;lt;br&amp;gt;&lt;br /&gt;
 int ISHELL_SendEvent(IShell *po, AEECLSID cls, AEEEvent eCode, uint16 wParam, uint32 dwParam);&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(ISHELL_SendEvent)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr_opaque(ISHELL_SendEvent,po)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create a user-mangled dynamic delegate for the function ISHELL_SendEvent.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add the instrumentation to the calling application&#039;s code:&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#ifdef srIMON&amp;lt;br&amp;gt;&lt;br /&gt;
 #define &amp;lt;groupid-name&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 #include &amp;lt;name&amp;gt;IM.h&amp;lt;br&amp;gt;&lt;br /&gt;
 #endif&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows you to dynamically intercept the call for the application under test.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Casting_and_pointers&amp;diff=3488</id>
		<title>Studio:Casting and pointers</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Casting_and_pointers&amp;diff=3488"/>
		<updated>2008-02-04T23:31:41Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A cast must be applied to a pointer before anything else. In other words, you must apply scl_cast before scl_ptr, as illustrated by the following example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(GetUnicodeName)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_cast (GetUnicodeName, name, unsigned short*)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr (GetUnicodeName, name,  OUT,  PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_string (GetUnicodeName, name, 100)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Can_an_array_be_cast_to_a_pointer%3F&amp;diff=3487</id>
		<title>Studio:Can an array be cast to a pointer?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Can_an_array_be_cast_to_a_pointer%3F&amp;diff=3487"/>
		<updated>2008-02-04T23:31:24Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No. You cannot cast an array to a pointer type. Because there are subtle differences between them, they are not always interchangeable in SCL like they are in C.&lt;br /&gt;
&lt;br /&gt;
Instead of using the following:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;INT vr_get_foo(INT entry, INT index, file_table_t * out_buffer)&amp;lt;br&amp;gt;&lt;br /&gt;
 typedef struct&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
     register ringer_types_t ringer_type;&amp;lt;br&amp;gt;&lt;br /&gt;
     BYTE alias_filename[(MAX_RINGER_ALIAS_NAME_LEN+1) *2];&amp;lt;br&amp;gt;&lt;br /&gt;
     UINT16 pad;&amp;lt;br&amp;gt;&lt;br /&gt;
 }ringer_file_table_t;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_function(v_get_mmedia_ringer)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(vr_get_mmedia_ringer, out_buffer, OUT, PRIVATE)&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this SCL instead:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_function(vr_get_mmedia_ringer)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_ptr(vr_get_get_mmedia_ringer, out_buffer, OUT, PRIVATE)&amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_string(ringer_file_table_t, alias_filename, (MAX_RINGER_ALIAS_NAME_LEN+1) * 2)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Can_STRIDE_marshal_both_data_and_pointers%3F&amp;diff=3486</id>
		<title>Studio:Can STRIDE marshal both data and pointers?</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Can_STRIDE_marshal_both_data_and_pointers%3F&amp;diff=3486"/>
		<updated>2008-02-04T23:30:57Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STRIDE does not marshal both the pointer value and the data. You have to pick one of the two. If a pointer is defined as void or the scl_ptr_opaque pragma is applied the pointer value is marshaled otherwise the data the pointer points to is marshaled. Opaque pointers can be passed to other functions or helper function to retrieve the data to which it points.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Accessing_target_data_while_processing_a_proxy_call&amp;diff=3484</id>
		<title>Studio:Accessing target data while processing a proxy call</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Accessing_target_data_while_processing_a_proxy_call&amp;diff=3484"/>
		<updated>2008-02-04T23:29:44Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In some cases, void pointers are passed into proxy functions calls, or the passed structures are so complex that they cannot completely be described for STRIDE. In these cases, the proxy (e.g., a script) might have to access certain data on the target to be able to validate the functionality of the call. For example, this might be required with an interface that writes structured data to a file:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;int write(const void *buffer, int element_size, int count)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
STRIDE needs to know the data structure in order to correctly marshal the data across platforms. The element size itself is not enough information for STRIDE. The buffer pointer could be typecast to a byte pointer; however, in this case the number of elements would be based on element size and count. STRIDE supports sized pointers, as long as the size is a single field and not the combination of multiple fields.&lt;br /&gt;
&lt;br /&gt;
How can an interface like this be easily dealt with in STRIDE if we plan on testing an application which uses this interface, but the library which implements the functionality is not yet available?&lt;br /&gt;
&lt;br /&gt;
First of all, the assumption is the actual structure is of no interest. We simply want to test the ability to write to a stream and later read from it, and verify we get the same data back. In this case, we can leave the buffer pointer as a void pointer and just pass the void pointer to STRIDE. Once in the proxy function, we need a way to retrieve the actual data at this pointer address from the target; this can be done with a helper function which reads a number of bytes from a certain memory address and passes it back to STRIDE. A simple helper function in the .h file perform this function:&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;tt&amp;gt;static void SCL_get_num_bytes(void *ptr, unsigned char* data, int num_bytes)&lt;br /&gt;
 {&lt;br /&gt;
     memcpy(data, ptr, num_bytes);&lt;br /&gt;
 }&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An important note is that the data has to be valid when the helper function is called. In the case of a proxy call, the pointer should certainly be valid until the function returns. The proxy script is as follows:&lt;br /&gt;
    write.owner.register event = ascript.WaitForEvent(); &lt;br /&gt;
    if (event = write)&lt;br /&gt;
    {&lt;br /&gt;
       /* Copy the buffer pointer from the proxy call */&lt;br /&gt;
       scl_get_num_bytes.ParameterList.num_bytes = write.ParameterList.element_size *write.ParameterList.count;    &lt;br /&gt;
      &lt;br /&gt;
       /* Call the helper function to retrieve the data */ &lt;br /&gt;
       scl_get_num_bytes.Call();&lt;br /&gt;
      &lt;br /&gt;
       /* Process the data */ &lt;br /&gt;
       get_num_bytes.User.OutPointers.data ...     ...     &lt;br /&gt;
       &lt;br /&gt;
       write.Return();  &lt;br /&gt;
       /* return from the proxy function call */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The same can be done for the read function. Once the read proxy is called, a helper function can be called to copy the actual data in place. The read interface is as follows:&lt;br /&gt;
&lt;br /&gt;
   int read(void *buffer, int element_size, int count);&lt;br /&gt;
   static void SCL_set_num_bytes(void *ptr, unsigned char* data, int num_bytes)&lt;br /&gt;
   {&lt;br /&gt;
     memcpy(ptr, data, num_bytes);&lt;br /&gt;
   }&lt;br /&gt;
   read.owner.register event = ascript.WaitForEvent();&lt;br /&gt;
   if (event = read)&lt;br /&gt;
   {&lt;br /&gt;
     /* set the data to be read */&lt;br /&gt;
     set_num_bytes.User.ParameterList.data = ...     ...   &lt;br /&gt;
      &lt;br /&gt;
     /* copy the buffer pointer from the proxy call */ &lt;br /&gt;
     scl_set_num_bytes.ParameterList.ptr = read.ParameterList.buffer;&lt;br /&gt;
     &lt;br /&gt;
     /* calculate the number of bytes */     &lt;br /&gt;
     scl_set_num_bytes.ParameterList.num_bytes = read.ParameterList.element_size *read.ParameterList.count;  &lt;br /&gt;
     &lt;br /&gt;
     /* Call the helper function to retrieve the data */     &lt;br /&gt;
     scl_set_num_bytes.Call();     &lt;br /&gt;
     &lt;br /&gt;
     /* Process the data */     &lt;br /&gt;
     read.Return();  /* return from the proxy function call */&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Applying_pragmas_up_and_down_type_chains&amp;diff=3483</id>
		<title>Studio:Applying pragmas up and down type chains</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Applying_pragmas_up_and_down_type_chains&amp;diff=3483"/>
		<updated>2008-02-04T23:29:26Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When a type T is pragmatized, it also applies to any types that are defined in terms of T.&lt;br /&gt;
&lt;br /&gt;
In the following SCL, Example 1 demonstrates when the scl_union pragma has no effect on pS, S1, or pS1. This is by design. In order for the pragma to apply, it must be structured as shown in Example 2.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example 1&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct {&amp;lt;br&amp;gt;&lt;br /&gt;
 enum {A,B}  discrim;&amp;lt;br&amp;gt;&lt;br /&gt;
 union &amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
    int x;&amp;lt;br&amp;gt; &lt;br /&gt;
    float f; &amp;lt;br&amp;gt;&lt;br /&gt;
   } u;&amp;lt;br&amp;gt; &lt;br /&gt;
 } S, *pS, S1, *pS1; &amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union(S, u, discrim);  &amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example 2&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;tt&amp;gt;typedef struct {&amp;lt;br&amp;gt;&lt;br /&gt;
 enum {A,B}  discrim;&amp;lt;br&amp;gt;&lt;br /&gt;
 union&amp;lt;br&amp;gt;&lt;br /&gt;
   {&amp;lt;br&amp;gt;&lt;br /&gt;
     int x; &amp;lt;br&amp;gt;&lt;br /&gt;
     float f; &amp;lt;br&amp;gt;&lt;br /&gt;
   } u;&amp;lt;br&amp;gt; &lt;br /&gt;
 } S;&amp;lt;br&amp;gt; &lt;br /&gt;
 typedef S* pS;  &amp;lt;br&amp;gt;&lt;br /&gt;
 #pragma scl_union(S, u, discrim); &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>https://www.stridewiki.com/index.php?title=Studio:Advantages_and_disadvantages_of_%22default%22_candidates&amp;diff=3482</id>
		<title>Studio:Advantages and disadvantages of &quot;default&quot; candidates</title>
		<link rel="alternate" type="text/html" href="https://www.stridewiki.com/index.php?title=Studio:Advantages_and_disadvantages_of_%22default%22_candidates&amp;diff=3482"/>
		<updated>2008-02-04T23:29:02Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following table describes the advantages and disadvantages associated with the &amp;quot;default&amp;quot; candidate method vs. the candidate method.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;, cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
! &lt;br /&gt;
&lt;br /&gt;
! &#039;&#039;&#039;&amp;quot;Default&amp;quot; candidate method&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
! &#039;&#039;&#039;Candidate method&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039;Define and pragmatize each function prototype&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
| Not needed.&lt;br /&gt;
&lt;br /&gt;
| Cumbersome if there are hundreds of candidate functions. &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039;Code footprint of the generated code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
| Only the proxy/stub of the &amp;quot;default&amp;quot; candidate is generated; thus, the code footprint is much smaller. &lt;br /&gt;
&lt;br /&gt;
| The code footprint is dependent upon how many candidates are defined using the scl_ptr_flist() pragma, since a proxy/stub is generated for each candidate defined in the list.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039;Capturing of function callback command/response payloads via the trace module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
| Any function callback command/response payloads with the identical signature can be captured.  &lt;br /&gt;
&lt;br /&gt;
| Only those candidate functions defined in the scl_ptr_flist() pragma can be captured.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &#039;&#039;&#039; Visibility of function callbacks via the trace module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
| The function callback being called is unknown. All of the function callbacks with the identical signature will be displayed with the &amp;quot;default&amp;quot; candidate name and SMID. &lt;br /&gt;
&lt;br /&gt;
| All of the function callbacks being called are known, as long as the candidate functions were declared in the scl_ptr_flist() pragma.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
One disadvantage of using the shorthand method to define candidates in scl_ptr_flist(), as shown in Method 3 of the [[Working with &amp;quot;default&amp;quot; candidates]] topic, is that the function pointer prototypes are not defined by the user/customer, but rather by STRIDE. So, for example, if the user wants to create a proxy for foo2() with stub candidate functions C2 and &amp;quot;cand4&amp;quot; on the target, the generated IM code will give &amp;quot;undefined&amp;quot; compiler errors for &amp;quot;cand4&amp;quot;. The following procedure using the header file MyHeader.h (the file containing the SCL pragmas or function prototypes) resolves this issue:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#ifdef srIMON&amp;lt;br&amp;gt;&lt;br /&gt;
 void cand4(int x, char y);&amp;lt;br&amp;gt;&lt;br /&gt;
 #endif &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The use of the srIMON preprocessor directive allows the SDAC to compile the file without any name conflicts for &amp;quot;cand4&amp;quot;, since these are already defined within STRIDE. It also allows the generated IM code to compile successfully.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyFunctions.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyFunctions.c is an example of a user-created file containing the actual code for the candidate &amp;quot;cand4&amp;quot;:&lt;br /&gt;
 &amp;lt;tt&amp;gt;void cand4(int x, char y)&amp;lt;br&amp;gt;&lt;br /&gt;
 { &amp;lt;br&amp;gt;&lt;br /&gt;
 } &amp;lt;br&amp;gt; &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyTest.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyTest.c is an example of a user-created file containing a test thread that makes the call to foo2() with the appropriate function pointer callback:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include “MyHeader.h”&amp;lt;br&amp;gt;&lt;br /&gt;
 FPtr funcPtr;&amp;lt;br&amp;gt;&lt;br /&gt;
 // set to cand4&amp;lt;br&amp;gt;&lt;br /&gt;
 funcPtr = cand4;&amp;lt;br&amp;gt;&lt;br /&gt;
 foo2(&amp;amp;funcPtr);&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In some instances, the candidates on the target are not known to the implementer of foo2() and the candidates may be static, so the above solution isn’t applicable. Using the “default” candidate mechanism is the perfect solution to this problem. The following example demonstrates how to do this (refer to Method 3 above):&lt;br /&gt;
&lt;br /&gt;
In MyHeader.h (the file that contains the SCL pragma’s or the function prototypes), replace the following:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_ptr_flist(*foo2.pFPtr, “cand4”, C2)&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
 &amp;lt;tt&amp;gt;#pragma scl_ptr_flist(*foo2.pFPtr, “default_cand”) // default candidate&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyFunctions.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyFunctions.c is an example of a user-created file containing the actual code for the candidates (unknown_cand1, unknown_cand2):&lt;br /&gt;
 &amp;lt;tt&amp;gt;static void unknown_cand1(int x, char y)&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;br&amp;gt;&lt;br /&gt;
 static void unknown_cand2(int x, char y)&amp;lt;br&amp;gt;&lt;br /&gt;
 {&amp;lt;br&amp;gt;&lt;br /&gt;
 }&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyTest.c&#039;&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
MyTest.c is an example of a user-created file containing a test thread that makes the call to foo2() with the appropriate function pointer callback.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;#include “MyHeader.h”&amp;lt;br&amp;gt;&lt;br /&gt;
 FPtr funcPtr;&amp;lt;br&amp;gt;&lt;br /&gt;
 // set to unknown_cand1&amp;lt;br&amp;gt;&lt;br /&gt;
 funcPtr = unknown_cand1;&amp;lt;br&amp;gt;&lt;br /&gt;
 foo2(&amp;amp;funcPtr);&amp;lt;br&amp;gt;&lt;br /&gt;
 // set to unknown_cand2&amp;lt;br&amp;gt;&lt;br /&gt;
 funcPtr = unknown_cand2;&amp;lt;br&amp;gt;&lt;br /&gt;
 foo2(&amp;amp;funcPtr);&amp;lt;br&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
</feed>