Follow-on fix for bug 457825. Use sheet principal for agent and user sheets. r=dbaron...
[wine-gecko.git] / embedding / wrappers / DotNETEmbed / ManagedGecko.html
blobb26f02536ed839caaa1be80d52eecb59f1f7acad
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
3 <head>
4 <meta http-equiv="content-type"
5 content="text/html; charset=ISO-8859-1">
6 <title>Convert Gecko from unmanged to managed code in .Net</title>
7 </head>
8 <body>
9 <h1 style="margin-left: 40px; text-align: center;">Wrapping Gecko APIs
10 using Microsoft Visual Studio .NET Managed Extensions for C++<big><big><big><br
11 style="color: rgb(255, 0, 0);">
12 </big></big></big> </h1>
13 <div style="text-align: center;"> <big><big><big><span
14 style="color: rgb(255, 0, 0);">**DRAFT**</span></big></big></big><br>
15 </div>
16 <br>
17 <h2>Intended Audience:</h2>
18 This paper is intended for a C++ programmer who would like to know how
19 to wrap Gecko engine from unmanaged C++ to managed C++ .&nbsp; Author
20 assumes the reader is familiar with Gecko and MS Visual Studio.NET with
21 Managed Extensions for C++.&nbsp; <br>
22 <br>
23 <h2>Background:</h2>
24 <ol>
25 <li> Why do we go all this trouble?&nbsp; </li>
26 <li>When we have Gecko as ActiveX control, then why don't we use the
27 Runtime-Callable Wrapper (RCW) and COM-Callable Wrapper (CCW)?&nbsp; </li>
28 </ol>
29 <br>
30 <h2 class="dtH1">How do we do this?</h2>
31 There are few ways to convert the existing unmanaged code to managed
32 code:
33 <ol type="1">
34 <li>You can use the built-in .NET runtime interop facilities (such as
35 PInvoke or COM Interop)<br>
36 </li>
37 <li>You can wrap the unmanaged code using the managed extensions to
38 C++.</li>
39 <li>You can rewrite the entire code in a .NET language.</li>
40 </ol>
41 <h2 class="dtH1">What do we need?</h2>
42 We need <br>
43 <ol>
44 <li>.NET Framework (1.1) <br>
45 </li>
46 <li>Microsoft Visual Studio .NET (preferably 2003)</li>
47 <li>mozilla development environment
48 (http://www.mozilla.org/build/win32.html)<br>
49 </li>
50 </ol>
51 <h2>Terminology:</h2>
52 Following terms are used throughout out this document and it is
53 important to understand what each term means.&nbsp; <br>
54 <ul>
55 <li><span style="font-weight: bold;">Assembly</span><br>
56 </li>
57 </ul>
58 <div style="margin-left: 80px;">Assembly is a building block of the
59 .Net Framework.&nbsp; It is the fundamental unit of deployment, version
60 control, reuse, activation, scoping, and security permissions.&nbsp; It
61 provides the Common Language Runtime (CLR) with the information it needs
62 to be aware of type implementations.&nbsp; It is a collection of types
63 and resources that are built to work together and form a logical unit of
64 functionality.&nbsp; <br>
65 </div>
66 <ul style="font-weight: bold;">
67 <li>Global Assembly Cache</li>
68 </ul>
69 <div style="margin-left: 80px;">Global Assembly Cache is a machine wide
70 code cache that is installed whereever the CLR is installed.&nbsp; In
71 most cases, if you intend to share an assembly with multiple
72 applications, you should deploy it into the global assembly cache.<br>
73 </div>
74 <ul>
75 <li><span style="font-weight: bold;">Managed code vs Unmanaged code</span><br>
76 </li>
77 </ul>
78 <div style="margin-left: 80px;"><span style="font-style: italic;">Manged
79 code</span> requires the execution environment of the CLR.&nbsp;
80 Compilers emit managed code as MSIL, the intermidate language.&nbsp; The
81 reason for the name is that code is managed by the CLR and objects are
82 allocated from heaps managed by the CLR.<br>
83 </div>
84 <div style="margin-left: 80px;"><span style="font-style: italic;">Unmanaged
85 code</span> does not use nor require the execution environment of the
86 Common Language Runtime (CLR).&nbsp; Unmanaged code is outside the
87 reach of the CLR's security system, garbage collector and other
88 services.</div>
89 <ul>
90 <li style="font-weight: bold;">CLR</li>
91 <li style="font-weight: bold;">Runtime-Callable Wrapper (RCW)</li>
92 <li style="font-weight: bold;">COM-Callable Wrapper (CCW)</li>
93 <li style="font-weight: bold;">Boxing</li>
94 </ul>
95 <div style="margin-left: 80px;">Boxing is a technique to convert a
96 value type to a __gc object by using the __box<br>
97 <div style="margin-left: 40px;">Int32 i = 42;<br>
98 __box Int32* b = __box(i);<br>
99 </div>
100 </div>
101 <ul>
102 <li style="font-weight: bold;">UnBoxing</li>
103 </ul>
104 <div style="margin-left: 80px;">UnBoxing (dereferencing) is a technique
105 to convert a boxed object to value type by casting.<br>
106 <div style="margin-left: 40px;">Color red;<br>
107 Object* obj = Enum::Parse(__typeof(Color), S"red");<br>
108 red = *static_cast&lt;__box Color*&gt;(obj);<br>
109 </div>
110 </div>
111 <br>
112 <ul>
113 <li style="font-weight: bold;">Managed Objects</li>
114 </ul>
115 <div style="margin-left: 80px;">Managed Object is an instance of a
116 class which is created in the heap and managed by the garbage collector
117 by using the <span style="font-style: italic;">__gc</span>
118 modifier.&nbsp; <br>
119 <div style="margin-left: 40px;"><span style="font-style: italic;">__gc</span>
120 class Point<br>
121 {<br>
122 </div>
123 <div style="margin-left: 80px;">public:<br>
124 </div>
125 <div style="margin-left: 120px;"> int x;<br>
126 int y;<br>
127 </div>
128 <div style="margin-left: 40px;"> };<br>
129 </div>
130 </div>
131 <ul style="font-weight: bold;">
132 <li>Value Types</li>
133 </ul>
134 <div style="margin-left: 80px;">Value Types ar typically small, short
135 lived objects and they are usually created on the stack. In managed C++,
136 the value types are defined by using <span style="font-style: italic;">__value</span>
137 modifier.&nbsp; <br>
138 <div style="margin-left: 40px;"><span style="font-style: italic;">__value</span>
139 class Point<br>
140 {<br>
141 </div>
142 <div style="margin-left: 80px;">public:<br>
143 </div>
144 <div style="margin-left: 120px;"> int x;<br>
145 int y;<br>
146 </div>
147 <div style="margin-left: 40px;"> };<br>
148 </div>
149 </div>
150 <br>
151 <h2>Necessary Steps:</h2>
152 <ul>
153 </ul>
154 <br>
155 <h2>Gecko APIs</h2>
156 We will be exposing list of Gecko APIs<br>
157 <ul>
158 <li>nsresult NS_InitEmbedding(nsILocalFile *aMozBinDirectory,
159 nsIDirectoryServiceProvider *aAppFileLocProvider);<br>
160 </li>
161 <li>nsresult NS_TermEmbedding();</li>
162 <li>...<br>
163 </li>
164 </ul>
165 <br>
166 <h2>Coding Techniques:</h2>
167 <ul>
168 <li>
169 <h3>Using managed object in unmanaged code</h3>
170 </li>
171 </ul>
172 <div style="margin-left: 40px;">Managed pointers are managed by the
173 garbage collector so that when copies are made, the gc knows that
174 references are created.&nbsp; When a pointer is passed to native code,
175 the gc cannot track its usage and so cannot determine any change in
176 object reference.&nbsp;&nbsp; Furthermore, if a garbage collection
177 occures, the object can be moved in memory, so the gc changes all
178 managed pointers so that they point to the new location.&nbsp; Because
179 the gc doesn't have access to the pointers passed to native code
180 (unmanaged code), potentially a pointer used in native code could
181 suddenly become invalid.&nbsp; Use a pinned pointer which tells gc not
182 to move the memory.<br>
183 <div style="margin-left: 80px;">
184 <table cellpadding="2" cellspacing="2" border="1"
185 style="text-align: left; width: 100%;">
186 <tbody>
187 <tr>
188 <td style="vertical-align: top;">//Using pinning<br>
189 #progma unmanaged<br>
190 void print(int *p)<br>
191 {<br>
192 &nbsp;&nbsp;&nbsp; printf("%ld\n", *p);<br>
193 }<br>
194 <br>
195 #progma managed<br>
196 _gc struct Test {<br>
197 &nbsp;&nbsp;&nbsp; int i;<br>
198 };<br>
199 <br>
200 void main()<br>
201 {<br>
202 &nbsp;&nbsp;&nbsp; Test * t = new Test;<br>
203 &nbsp;&nbsp;&nbsp; int __pin* p = &amp;t-&gt;i;<br>
204 &nbsp;&nbsp;&nbsp; print(p);<br>
205 }<br>
206 </td>
207 </tr>
208 </tbody>
209 </table>
210 </div>
211 </div>
212 <div style="margin-left: 40px;"><br>
213 </div>
214 <ul>
215 <li>
216 <h3>Using unmanaged object in managed code</h3>
217 </li>
218 </ul>
219 <div style="margin-left: 120px;">
220 <table cellpadding="2" cellspacing="2" border="1"
221 style="text-align: left; width: 100%;">
222 <tbody>
223 <tr>
224 <td style="vertical-align: top;"><span class="clsCap">//Using
225 GCHandle</span> <br>
226 <pre>#using &lt;mscorlib.dll&gt;<br><br>using namespace System;<br>using namespace System::Runtime::InteropServices;<br><br>#pragma managed<br>class AppDomainWrapper<br>{<br>private:<br> int m_handle;<br>public:<br> AppDomainWrapper() {<br> AppDomain* d = AppDomain::Current;<br> m_handle = (GCHandle::op_Explicit(GCHandle::Alloc(d))).ToInt32();<br> }<br> ~AppDomainWrapper() {<br> (GCHandle::op_Explicit(m_handle)).Free();<br> }<br> // more functions here...<br> void PrintBaseDir() {<br> AppDomain* domain = __try_cast&lt;AppDomain*&gt;(<br> (GCHandle::op_Explicit(m_handle)).Target);<br> Console::WriteLine ( S"AppDomain Base Directory: {0}",<br> domain-&gt;BaseDirectory );<br> }<br>};<br><br>#pragma unmanaged<br>int main() {<br> AppDomainWrapper w; <br> w.PrintBaseDir();<br> return 0; <br>}</pre>
227 </td>
228 <td style="vertical-align: top;"><span class="clsCap">//Using
229 gcroot</span> <br>
230 <pre>#using &lt;mscorlib.dll&gt;<br>#include &lt;gcroot.h&gt;<br><br>using namespace System;<br>using namespace System::Runtime::InteropServices;<br><br>#pragma managed<br>class AppDomainWrapper<br>{<br>private:<br> gcroot&lt;AppDomain*&gt; m_domain;<br>public:<br> AppDomainWrapper() {<br> m_domain = AppDomain::CurrentDomain;<br> }<br> ~AppDomainWrapper() {<br> }<br> // more functions here...<br> void PrintBaseDir() {<br> Console::WriteLine ( S"AppDomain Base Directory: {0}",<br> m_domain-&gt;BaseDirectory );<br> }<br>};<br><br>#pragma unmanaged<br>int main() {<br> AppDomainWrapper w; <br> w.PrintBaseDir();<br> return 0; <br><br><br><br>}</pre>
231 </td>
232 </tr>
233 </tbody>
234 </table>
235 <span class="clsFigure"></span><span class="clsCap"></span> </div>
236 <h2>Useful Tools:</h2>
237 <ul>
238 <li>Viewing Assembly Contents</li>
239 <ul>
240 <li>MSIL Disassembler (ildasm.exe)<br>
241 </li>
242 </ul>
243 </ul>
244 <ul>
245 <li>TLBIMP.exe</li>
246 <li>TLBEXP.exe</li>
247 <li>REGASM.exe</li>
248 <li>AXIMP.exe</li>
249 <li>REGSVCS.exe</li>
250 </ul>
251 <br>
252 <h2 class="dtH1">References<br>
253 </h2>
254 <ul>
255 <li>Visual Studio .NET
256 (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vsstartpage.asp)<br>
257 </li>
258 <li>Managed Extensions for C++ programming (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmex/html/vcconmcoverview.asp)</li>
259 <li>Managed Extensions for C++ specifications
260 (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/vcManagedExtensionsSpec_Start.asp)<br>
261 </li>
262 </ul>
263 <h2><br>
264 </h2>
265 <h2>History:</h2>
266 Draft 0.1 : April 9 2003&nbsp; Roy Yokoyama<br>
267 <br>
268 <br>
269 </body>
270 </html>