1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<HTML LANG="en-US"> 3 4<HEAD> 5 <META http-equiv="Content-Type" content="text/html; charset=utf-8"> 6 <META http-equiv="Content-Style-Type" content="text/css"> 7 8 <TITLE>DLL Manual</TITLE> 9 10 <STYLE> 11 h1.left 12 { 13 color: #46f; 14 font-size: 100%; 15 } 16 ul.left, ul.left ul 17 { 18 margin: 0; 19 padding: 0; 20 } 21 ul.left 22 { 23 font-size: 0.8em; 24 } 25 ul.left li 26 { 27 margin: 0; 28 padding: 0; 29 margin-left: 1em; 30 line-height: 1.5em; 31 } 32 ul.left li a 33 { 34 margin: 0; 35 padding: 0; 36 } 37 38 H1 39 { 40 font-weight : bold; 41 font-size : 250%; 42 text-align : left; 43 color : #46f; 44 margin-bottom : 0px; 45 } 46 47 H2 48 { 49 font-weight : normal; 50 font-size : 180%; 51 margin : 24pt 0pt 6pt 0pt; 52 border-bottom-style : solid; 53 border-bottom-width : 1px; 54 } 55 56 H3 57 { 58 font-weight : bold; 59 font-size : 120%; 60 border-bottom-style : solid; 61 border-bottom-width : 1px; 62 width: 75%; 63 margin : 18pt 0pt 6pt 30pt; 64 } 65 66 H4 67 { 68 font-weight : bold; 69 font-size : 100%; 70 margin : 12pt 0pt 6pt 30pt; 71 } 72 73 H5 74 { 75 font-weight : bold; 76 margin : 12pt 0pt 6pt 30pt; 77 } 78 79 H6 80 { 81 font-weight : bold; 82 margin : 12pt 0pt 6pt 30pt; 83 } 84 85 DIV.date 86 { 87 text-align : right; 88 color : #46f; 89 margin-bottom : 30pt; 90 line-height : 150%; 91 } 92 93 P 94 { 95 margin : 0pt 0pt 12pt 30pt; 96 line-height : 150%; 97 } 98 99 OL,UL,DL 100 { 101 margin : 6pt 0pt 6pt 50pt; 102 } 103 OL OL, UL UL 104 { 105 margin-left: 3em; 106 } 107 108 DT 109 { 110 font-family : "Courier New", monospace; 111 margin-top : 0.3em; 112 margin-bottom : 0.3em; 113 } 114 DD 115 { 116 margin-top : 0.3em; 117 margin-bottom : 0.6em; 118 } 119 120 PRE 121 { 122 font-family : "Courier New", monospace; 123 font-weight : normal; 124 125 margin : 0pt 0pt 20pt 50pt; 126 padding : 2pt 8pt 2pt 8pt; 127 background-color : #eee; 128 129 border-style : solid; 130 border-width : 1px; 131 } 132 em 133 { 134 font-style: normal; 135 color: red; 136 } 137 TABLE 138 { 139 margin-left : 40pt; 140 margin-bottom : 20pt; 141 border-color : #aaa; 142 border-width : 1pt; 143 border-style : solid; 144 } 145 TD 146 { 147 font-style : normal; 148 padding : 2pt 4pt 2pt 4pt; 149 150 border-color : #aaa; 151 border-width : 1pt; 152 border-style : solid; 153 } 154 div.footer 155 { 156 border-color: black; 157 padding-top: 0.5em; 158 border-top-style : solid; 159 border-top-width : 1px; 160 width: 100%; 161 margin-top: 2em;; 162 } 163 div.footer span 164 { 165 color : #46f; 166 float: right; 167 } 168 table 169 { 170 border-collapse: collapse; 171 } 172 table td 173 { 174 } 175 table th 176 { 177 border : solid 1px; 178 } 179 ul 180 { 181 margin-top: 1em; 182 margin-bottom: 1em; 183 } 184 span.here 185 { 186 color: red; 187 } 188 DL.history 189 { 190 margin: 1em; 191 } 192 DL.history DT 193 { 194 font-family : sans-serif; 195 font-weight : bold; 196 font-size : 0.8em; 197 margin : 0px; 198 } 199 DL.history DD 200 { 201 font-size : 0.9em; 202 margin : 0px 0px 4px 0px; 203 } 204 205 </STYLE> 206 <SCRIPT type="text/javascript"> 207 <!-- 208 function DeleteRule(index) 209 { 210 var ss = document.styleSheets.item(0); 211 212 if( ss.removeRule ) 213 { 214 ss.removeRule(index); 215 } 216 else 217 { 218 ss.deleteRule(index); 219 } 220 } 221 function OnClickAnchor(e, anchor) 222 { 223 window.parent.frames[1].location.hash = anchor; 224 225 if( e.preventDefault ) 226 { 227 e.preventDefault(); 228 } 229 else 230 { 231 e.returnValue = false; 232 } 233 } 234 function TravLeft(obj) 235 { 236 var ary = new Array(); 237 var index = 0; 238 239 for( var i = 0; i < obj.childNodes.length; ++i ) 240 { 241 var c = obj.childNodes.item(i); 242 243 if( c.nodeType == 1 ) 244 { 245 if( c.tagName == "H2" || c.tagName == "H3" ) 246 { 247 var text = "--no name--"; 248 249 var anchor = "name-" + index; 250 index++; 251 252 if( c.hasChildNodes() ) 253 { 254 var a = c.childNodes.item(0); 255 256 if( a && a.tagName == "A" ) 257 { 258 text = a.innerHTML; 259 } 260 else 261 { 262 text = c.innerHTML; 263 } 264 } 265 266 ary.push([c.tagName.substr(1,1), "<a target=\"right\" href=\"?right#" + anchor + "\" onclick=\"OnClickAnchor(event, '" + anchor + "')\">" + text + "</a>"]); 267 } 268 else 269 { 270 ary = ary.concat(TravLeft(c)); 271 } 272 } 273 } 274 275 return ary; 276 } 277 function TravRight(obj) 278 { 279 var index = 0; 280 281 for( var i = 0; i < obj.childNodes.length; ++i ) 282 { 283 var c = obj.childNodes.item(i); 284 285 if( c.nodeType == 1 ) 286 { 287 if( c.tagName == "H2" || c.tagName == "H3" ) 288 { 289 var anchor = "name-" + index; 290 index++; 291 292 c.innerHTML = "<a name=\"" + anchor + "\">" + c.innerHTML + "</a>" 293 } 294 else 295 { 296 TravRight(c); 297 } 298 } 299 } 300 } 301 function OnLoad_Left() 302 { 303 var test = TravLeft(document.body); 304 var test2 = ""; 305 var level = 2; 306 307 test2 += "<h1 class='left'>" + document.title + "</h1>"; 308 test2 += "<ul class='left'>"; 309 for( var i in test ) 310 { 311 while( test[i][0] > level ) 312 { 313 level++; 314 test2 += "<ul>"; 315 } 316 while( test[i][0] < level ) 317 { 318 level--; 319 test2 += "</ul>"; 320 } 321 322 test2 += "<li>" + test[i][1]; 323 } 324 test2 += "</ul>"; 325 326 document.body.innerHTML = test2; 327 DeleteRule(0); 328 } 329 function OnLoad_Right() 330 { 331 TravRight(document.body); 332 } 333 function OnLoad_Frame() 334 { 335 var myname = location.pathname.substr(location.pathname.lastIndexOf("/") + 1); 336 337 var f = document.createElement("frameset"); 338 var l = document.createElement("frame"); 339 var r = document.createElement("frame"); 340 341 f.appendChild(l); 342 f.appendChild(r); 343 f.cols = "250,*"; 344 345 l.src = myname + "?left" + location.hash; 346 r.src = myname + "?right" + location.hash; 347 l.name = "left"; 348 r.name = "right"; 349 350 var h = document.documentElement; 351 var b = h.getElementsByTagName("body").item(0); 352 353 h.replaceChild(f, b); 354 } 355 356 357 if( ! window.opera ) 358 { 359 var search = location.search; 360 361 if( search == "?left" ) 362 { 363 window.onload = OnLoad_Left; 364 } 365 else if( search == "" ) 366 { 367 window.onload = OnLoad_Frame; 368 } 369 else if( search == "?right" ) 370 { 371 window.onload = OnLoad_Right; 372 } 373 374 if( search != "?right" ) 375 { 376 var ss = document.styleSheets.item(0); 377 378 if( ss.addRule ) 379 { 380 ss.addRule("body", "display: none", 0); 381 } 382 else 383 { 384 ss.insertRule("body {display: none}", 0); 385 } 386 } 387 } 388 //--> 389 </SCRIPT> 390</HEAD> 391 392<BODY> 393 394 395 396 397 398<H1>DLL Manual</H1> 399<DIV class="date">(2012/06/22)</DIV> 400 401 402 403 404 405<H2>Introduction</H2> 406 407<H3>About This Document</H3> 408<P> 409 This document provides information about the DLL mechanism that the CTR-SDK provides. 410</P> 411<ul> 412 <li>DLL Basics 413 <li>Features and Limitations of DLLs 414 <li>Basic API Usage 415 <li>Special Features 416</ul> 417 418<P> 419 Information about the following can be found in the referenced documentation. 420</P> 421<ul> 422 <li>Procedures for creating DLLs using the SDK build system:<br><i><a href="BuildSystemManualForDll.html" target="_parent">CTR-SDK Build System Manual (for DLLs)</a></i> 423 <li>Information about developing your own build system:<br><i><a href="BuildSystemDevelopmentGuideForDll.html" target="_parent">Guide to Developing a Build System (for DLLs)</a></i> 424<li>Information about developing a more sophisticated build system:<br><i><a href="BuildSystemDevelopmentGuideForDllAdvanced.html" target="_parent">Guide to Developing a Build System (for High-Level DLLs)</a></i> 425</ul> 426 427<P> 428This document assumes basic knowledge of CTR-SDK terminology. For a glossary of basic CTR-SDK terms, see the <i><a href="../Glossary/Glossary.html" target="_parent">CTR-SDK Terminology</a></i>. 429</P> 430 431<H3>Notation Used in This Document</H3> 432<P> 433Content in shaded boxes, as shown below, indicate a sequence to be entered on the command line. 434</P> 435<pre> 436nn::ro::Initialize(pCrs, crsSize); 437</pre> 438 439<P> 440Sample source code uses the following user-defined functions to make the code easier to understand. You must implement processing equivalent to these functions in your application. 441</P> 442<dl> 443<dt><CODE>s64 GetFileSize(const wchar_t* path)</CODE> 444 <dd> 445 Returns the size of the file specified by <SPAN class="argument">path</SPAN>. 446 447<dt><CODE>void* AllocateMemory(size_t size, int alignment)</CODE> 448 <dd> 449 Allocates a memory area of <SPAN class="argument">size</SPAN> bytes, in accordance with the alignment restrictions specified by <SPAN class="argument">alignment</SPAN>. 450 451<dt><CODE>void LoadFile(void* pBuffer, const wchar_t* path, size_t size)</CODE> 452 <dd> 453 Reads <SPAN class="argument">size</SPAN> bytes from the file specified by <SPAN class="argument">path</SPAN> into <SPAN class="argument">pBuffer</SPAN>. 454</dl> 455 456 457 458 459 460<H2>Terminology</H2> 461<P> 462 This section defines terminology relating to the DLL mechanism provided by the CTR-SDK. 463</P> 464<P> 465 The meanings and usage of terms used in this document and the CTR-SDK may differ from their general meanings and usage. 466</P> 467 468 469<dl> 470 <dt>Executable code 471 <dd> 472 Sequences of machine code interpreted and executed by the CPU, and constants and variables referenced directly from it. 473 474 <dt>Module 475 <dd> 476 A chunk of execution code divided into a meaningful unit. 477 478 <dt>Static module 479 <dd> 480The main application module, which contains <CODE>nnMain</CODE>. This module is the first module that is executed when application execution begins. 481 482 <dt>Dynamic module 483 <dd> 484 A module that can be loaded into memory and used dynamically. 485 486 <dt>DLL 487 <dd> 488 The mechanism for implementing a dynamic module. It can also refer to a dynamic module itself. 489 490 <dt>Symbol 491 <dd> 492 A meaningful location in a module. In most cases, the symbol is named, but sometimes it is not. 493 494 <dt>See Also 495 <dd> 496Use a symbol from another module. Refers to calling a function defined in another module, or reading and writing a variable defined in another module. 497 498 <dt>Resolve 499 <dd> 500Make the symbol being referenced available. It determines the address of a symbol so that a function can be called, or a variable read and written. 501 502 <dt>Export 503 <dd> 504 Make a module's symbol available for reference from another module. A symbol can only be referenced if it has been exported. 505 506 <dt>Export type 507 <dd> 508 Indicates the format in which information is referenced from other modules. Three export types are available in <CODE>ro</CODE>: <I>name</I>, <I>index</I>, and <I>offset</I>. 509 510 <dt>Import 511 <dd> 512 Declares a reference. The linker attempts to resolve symbols that have not been imported at link time. This normally results in an undefined symbol error. 513 514<dt>Exporting 515 <dd> 516 Same as "export." 517 518<!-- <dt>基本スタイル <dd> このドキュメントおよび SDK のビルドシステムがサポートする 5 種類の DLL の使い方のこと。 標準スタイル、ライブラリスタイル、プラグインスタイル、RSO スタイル、REL スタイルの 5 種類。 <dt>共有ライブラリ <dd> 複数の静的モジュールから単一の DLL を使用することを目的として構成した DLL のこと。 <br> 共有ライブラリ → 静的モジュールの順で開発が行われる。 <dt>RSO <dd> RVL-SDK で提供されている DLL 実装の一形式。 <dt>REL <dd> RVL-SDK で提供されている DLL 実装の一形式。 <dt>プラグイン <dd> 単一の静的モジュールから同じ I/F をもつ複数の DLL を使用することを目的として構成した DLL のこと。 <br> 静的モジュール → プラグインの順で開発が行われる。 --> 519<dt>RO File 520 <dd> 521 A format for implementing DLLs provided by the CTR-SDK. 522 523<dt>CRO File 524 <dd> 525The dynamic-module file format used by RO files. 526<dt>CRR File 527 <dd> 528A file that stores DLL registration information. It can store information for one or more CRO files. 529 530 <dt><CODE>cro.rlt</CODE> 531 <dd> 532 A file that stores DLL registration information. This file stores information for one CRO file. It is converted into a CRR file for use. 533 534 <dt><CODE>edit</CODE> 535 <dd> 536 A steering file used by the <CODE>ARMCC</CODE> linker. 537 538<dt>CRS File 539 <dd> 540 A file storing information about a static module. 541<dt>XRL File 542 <dd> 543A file format for storing export and reference symbol information for a module. 544<dt>UAE File 545 <dd> 546A command-line option file format specified to the <CODE>ARMCC</CODE> linker. 547<dt>RO library 548 <dd> 549The <CODE><a href="../../api/nn/ro/Overview.html">nn::ro namespace</a></CODE> section of the API provided by the CTR-SDK. It is a collection of functions for using DLLs. 550 551 <dt> 552 <dd> 553</dl> 554 555 556<H2>DLLs</H2> 557 558<H3>Static and Dynamic Modules</H3> 559<P> 560If an application does not use dynamic modules, all of its executable code is collected into a single file. 561 562When an application starts, all of its executable code is loaded into memory and maintained there until the application exits. The executable code is never modified while the application is running. 563 564 The executable code that is loaded upon startup is called the "static module." 565</P> 566<P> 567Meanwhile, if the application uses dynamic modules, it can split up its executable code into multiple modules. 568When the application starts, only the static module is loaded into memory. The static module is then able to load the dynamic modules, and thus run executable code including dynamic modules that can be loaded into and released from memory during program execution. 569</P> 570 571 572 573<H3>What You Can Do With a DLL</H3> 574 575<H4>Conserve Memory</H4> 576<P> 577 You can reduce the amount of memory that your code uses by breaking up your application into multiple modules, and loading them into memory only when needed, freeing them afterward. 578</P> 579<P> 580For example, you could put single-player mode and multiplayer mode into separate DLLs, and load just one of them depending on the play mode. This reduces your application's memory footprint by the size of the other mode. 581</P> 582 583<H4>Shorten Startup Time</H4> 584<P> 585When your application is started, it starts running after all of its static modules have been loaded into memory. The time it takes from the application's start instruction until <code>nnMain</code> starts executing is proportional to the size of the static modules. You can shorten the time it takes for your application's first screen to appear by putting just the minimum code needed to show the first screen in your static module, and putting the other portions of your application into DLLs, and loading them after the first screen appears. 586</P> 587 588 589 590 591<h3>Features and Limitations of the RO Format</h3> 592<P> 593The DLL mechanism provided by the CTR-SDK is called RO. 594</P> 595 596<h4>Features</h4> 597<P> 598The RO format features the following differences from other DLL implementations. 599</P> 600 601<ul> 602<li>Three export types.<br>One of three formats can be used for symbol resolution: <CODE>offset</CODE>, <CODE>index</CODE>, or <CODE>name</CODE>. Although you can select the format for each symbol individually, the SDK's build system only supports selection at the module level. For information about specifying export types, see <a href="BuildSystemManualForDll.html" target="_parent">CTR-SDK Build System Manual (for DLLs)</a> or <a href="BuildSystemDevelopmentGuideForDll.html" target="_parent">Guide to Developing a Build System (for DLLs)</a>. 603<li>Automatic resolution of references between modules.<br>The build system automatically resolves references between modules just by loading them, making functions and variables available. You can also get pointers to symbols manually. 604<li>The application developer loads DLLs into memory.<br>The application developer is responsible for loading DLLs into memory and handling where they are allocated in memory. 605<li>Support for C++.<br>You can code DLLs in C++. You can also reference and resolve C++ symbols between modules. <br><STRONG>Note:</STRONG> If you get pointers to C++ symbols manually, you must use the mangled names. 606<li>Ability to pass C++ exceptions across module boundaries.<br>You can <CODE>throw</CODE> an exception from one module and <CODE>catch</CODE> it in another. 607<li>Support for automating imports and exports.<br>Although this feature is not part of the RO format itself, the SDK provides a tool to support automation of imports and exports. When you use the SDK's build system, it uses this tool to perform imports and exports automatically. You can also use this tool to strip dead code automatically. 608</ul> 609 610<h4>Upper Limit</h4> 611<P> 612The RO format has the following limitations. 613</P> 614<ul> 615<li>Each module can export no more than 65,535 symbols by name. 616<li>The maximum length of a symbol that can be exported by name is 8,192 characters. 617</ul> 618 619<h4><a name="restriction">Restrictions</a></h4> 620<P> 621The RO format has the following restrictions. 622</P> 623<ul> 624<li>Template class static member variables defined in a header and instances of static local variables in inline functions must be included in static modules. For more information, see <a href="#vague_linkage">Handling for Overloaded Symbols</a>. 625<li>You cannot include symbols belonging to the C Runtime (CRT) in dynamic modules. They are always included in static modules. The CRT includes standard C functions, in addition to <CODE>new</CODE>, <CODE>delete</CODE>, and other language features implemented as internal function calls, such as integer division and 64-bit arithmetic. 626<li>You cannot define static variables or constants specifying an alignment greater than 8 bytes. Alignment restrictions greater than 8 bytes are ignored. 627<li>Functionality may not be as intended when you use <CODE>weak</CODE> symbols and other features that are not part of the C/C++ language standards. 628</ul> 629<P> 630In the RO format, you can make and use any static library (<CODE>.a</CODE>) as a DLL. But because of these restrictions, if you intend to use a static library as a DLL, be sure to confirm with the library's creator that it can be made and used as a DLL. 631</P> 632<P> 633 The static libraries (<code>.a</code>) provided in the SDK must not be made and used as DLLs. That is prohibited. 634</P> 635 636 637<h3>RO File Structure</h3> 638<P> 639 If you did not use DLLs, you would develop CTR applications by creating CXI and CCI files from AXF files. If you use DLLs, you must additionally create CRS, CRR, and CRO files. 640</P> 641 642<h4>CRS Files</h4> 643<P> 644 A CRS file stores reference and export information for static modules. It is used to resolve symbols between DLLs. It does not contain executable code. 645</P> 646<h4>CRR Files</h4> 647<P> 648 A CRR file contains CRO management information. It also contains information necessary for debugging DLLs. 649</P> 650<P> 651CRR files have an important limitation: they must be stored on the ROM-FS, directly under the <CODE>.crr</CODE> directory, which is in turn directly under the ROM-FS root directory. (If the ROM-FS root directory is <code>/</code>, this directory is <code>/.crr</code>.) The <code>.crr</code> directory must not contain any file other than the CRR file. 652</P> 653 654<h4>CRO Files</h4> 655<P> 656 A CRO file is a dynamic module. It stores executable code and information necessary to resolve symbols between the application's various modules. 657</P> 658 659 660 661 662 663 664 665<H2>Creating Dynamic Modules</H2> 666 667<H3>Creating the Source Code</H3> 668<P> 669There are no special requirements for the source code of a dynamic module, with the exception of a few limitations. You can create them in the same manner as static modules. As with ordinary code, the only actions you need to take to call functions and reference variables across modules are to share headers and code the calls and references. 670</P> 671<P> 672For more information about the restrictions on dynamic modules, see <a href="#restriction">Restrictions</a>. 673</P> 674<P> 675You must add extra code to use DLL features. For more information, see <a href="#other_feature">Special Uses</a>. 676</P> 677 678 679 680<H3>Building DLLs</H3> 681<P> 682If you intend to use the SDK's build system, see <a href="BuildSystemManualForDll.html" target="_parent">CTR-SDK Build System Manual (for DLLs)</a>. If you plan to develop your own build system, see <a href="BuildSystemDevelopmentGuideForDll.html" target="_parent">Guide to Developing a Build System (for DLLs)</a>. 683</P> 684 685 686 687<H3><a name="choose_type">Selecting the Export Type</a></H3> 688<P> 689The RO format has three export types. You must select which export types to use when you create your CRO file. The following table shows the differences between the export types. 690</P> 691<table> 692<tr><th><th>Name<th>Index<th>Offset 693<tr><th>Size of the referencing CRO file<td>Large<td>Small<td>Small 694<tr><th>Size of the exporting CRO file<td>Large<td>Small<td>0 695<tr><th>Time required by <CODE>LoadModule</CODE><td>Long<td>Medium<td>Short 696<tr><th>Getting the pointer manually<td>Possible<td>Possible<td>No 697<tr><th>Creating the referencing module first<td>Possible<td>No<td>No 698<tr><th>Build steps<td>Normal<td>Normal<td>Many 699</table> 700<P> 701 <CODE>Name</CODE> has the greatest functionality, followed by <CODE>index</CODE> and then <CODE>offset</CODE>, and greater functionality comes at a correspondingly greater cost. 702</P> 703<P> 704Normally, it is fine to choose <CODE>offset</CODE> as the export type. If you want to get pointers manually (using <a href="../../api/nn/ro/Module/GetPointer.html"><code>GetPointer</code></a>) or use a DLL that functions as a library, choose <CODE>index</CODE> or <CODE>name</CODE>, depending on your needs. 705</P> 706 707<H3>Using Static Libraries</H3> 708<P> 709Static libraries can be embedded into dynamic modules. However, in addition to the <a href="#restriction">RO restrictions</a>, also note the following caution: 710</P> 711<ul> 712<li><b>Do not embed the same static library into multiple DLLs. </b><br>If you embed the same static library into multiple DLLs, there will be multiple global variables where there should only be one.The internal state in the library will not be what you intended. In particular, if you create a mutual exclusion object (mutex) as a global variable, it acts as if the library is not conducting mutual exclusion, even though it is treating the mutex correctly. In this case, sometimes a bug arises and sometimes it doesn't (depending on the timing), so debugging is difficult. Also, because the coding is correct in the source code, it is extremely difficult to find the bug. 713</ul> 714 715 716 717 718<H2>Creating Static Modules</H2> 719<H3>Creating the Source Code</H3> 720<P> 721Some variables require special treatment. For more information, see <a href="#vague_linkage">Handling for Overloaded Symbols</a>.<br/><br/> Other than taking care of the overloaded symbols, there is nothing special that must be done to reference DLL functions and variables. You simply share headers and reference the normal way. 722</P> 723<P> 724In the RO format, the management of DLLs is left entirely up to the application. To prepare memory for use by DLLs and to load DLLs you must implement everything with code in the application. For more information, see <a href="#use_dll">Using DLLs</a>. 725</P> 726<P> 727In addition, you must add extra code to use DLL features. For more information, see <a href="#other_feature">Special Uses</a>. 728</P> 729 730 731 732<H3>Building</H3> 733<P> 734If you intend to use the SDK's build system, see <a href="BuildSystemManualForDll.html" target="_parent">CTR-SDK Build System Manual (for DLLs)</a>. If you plan to develop your own build system, see <a href="BuildSystemDevelopmentGuideForDll.html" target="_parent">Guide to Developing a Build System (for DLLs)</a>. 735</P> 736 737 738 739<H3>Selecting the Export Type</H3> 740<P> 741You can select the export type, so that the static module also exports symbols for the dynamic module. <br/>Selecting export types for static modules is the same as selecting export types for dynamic modules. For more information, see the <a href="#choose_type">dynamic modules</a> section. 742</P> 743 744 745 746 747 748<H2><a name="vague_linkage">Handling of Symbols with Multiple Definitions</a></H2> 749<P> 750Overloaded symbols require special treatment. 751</P> 752 753<H3>Overloaded Symbols in C++</H3> 754<P> 755 Usually, having multiple instances of the same symbol in a single program is not permitted in the C/C++ programming languages. However, for the following elements in C++, the same symbol can be included in multiple object files and used normally. 756</P> 757<ul> 758<li>Template instances. 759<li>Inline functions that were not inlined. 760<li>Class member variables for the template class. 761<li>Static local variables in inline functions. 762<li>Type information. 763<li>Virtual tables. 764</ul> 765<P> 766Symbols for these elements are merged appropriately by the linker during linking, and an adjustment is made so that all the symbols become one in the overall program. 767</P> 768<H3>Handling of Overloaded Symbols in RO</H3> 769<P> 770Because the symbols are merged by a linker, they must be merged in each module. Also, because plug-in type use is supported in RO, multiple modules can contain the same symbol. As a result, an instance of the symbols for these elements exists in each module that is referenced. 771</P> 772<P> 773However, because usually symbols that represent variables among these elements are used with the assumption that all references are made to a unique instance, unintended results may occur if different instances are referenced in each module. 774</P> 775<P> 776To handle both situations, processes for variables and elements other than variables are separated in RO. Among symbols that are defined in multiple modules, for symbols that represent variables, an instance in the static module is always referenced, and all other symbols can be contained in every module. 777</P> 778<H3>Support for Overloaded Symbols</H3> 779<P> 780As described previously, when symbols that represent variables are defined in multiple modules, RO assumes that those symbol definitions are in the static module and then references them in the static module. 781</P> 782<P> 783If a definition that is referenced is not in the static module, an error occurs when linking the static module. In such cases, the code must be revised so that the static module contains a definition for the referenced symbol. 784</P> 785<P> 786If multiple definitions are not created (intentionally or accidentally), support is necessary for the following. 787</P> 788<ul> 789 <li>Class member variables for the template class. 790 <li>Static local variables in inline functions. 791</ul> 792<P> 793The definitions of symbols for these elements are created in object files created from the source files that referenced those symbols. Reference these symbols from the static module source files to make sure that the definitions are contained in the static module. Often these symbols cannot be directly referenced. The definitions can be included in the static module by using indirect methods such as referencing the function using the target variable. <br/>You can use <a href="../../api/nn_util/NN_UTIL_REFER_SYMBOL.html"><code>NN_UTIL_REFER_SYMBOL</code></a> for this purpose. 794</P> 795<P> 796For example, when a header such as the following is used, the conditions described previously apply because <code>ms_pInstance</code> is a template class class member variable. If the static module is not using a class <code>S</code> at all and the <code>S</code> class is used in multiple dynamic modules, <code>Singleton<S>::ms_pInstance</code> causes an error in the static modules at build time. 797</P> 798<P> 799 Header<br/> (Code from the very beginning.) 800</P> 801<PRE> 802... (omitted) ... 803 804template <class T> 805class Singleton 806{ 807public: 808 static T& GetInstance() { return *ms_pInstance; } 809 810protected: 811 Singleton() { ms_pInstance = static_cast<T*>(this); } 812 ~Singleton() { ms_pInstance = NULL; } 813 814private: 815 static T* ms_pInstance; 816}; 817 818template <class T> T* Singleton <T>::ms_pInstance = NULL; 819 820class S : public Singleton<S> 821{ 822}; 823 824... (omitted) ... 825</PRE> 826<P> 827 In this case, the following functions are added to source files and other files that include <code>nnMain</code>. These functions do not actually need to be called. 828</P> 829<P> 830 Any source files that are used in static modules. <br/> (Code added for RO support.) 831</P> 832<PRE> 833... (omitted) ... 834 835void DummyReference() 836{ 837 <span class="here">NN_UTIL_REFER_SYMBOL(S::GetInstance);</span> 838} 839</PRE> 840 841 842 843 844 845<H2><a name="use_dll">Using DLLs</a></H2> 846 847<H3>Basic Sequence</H3> 848<P> 849The following list shows the sequence from loading a single CRO file, to using it, and then freeing all memory. 850</P> 851 852<ol> 853<li>Load the CRS file into memory.<br> ↓ 854<li><code>nn::ro::Initialize(crs)</code><br> ↓ 855<li>Load the CRR file into memory.<br> ↓ 856<li><code>nn::ro::RegisterList(crr)</code><br> ↓ 857<li>Load the CRO file into memory.<br> ↓ 858<li><code>nn::ro::LoadModule(cro)</code><br> ↓ 859<li><code>pModule->DoInitialize()</code><br> ↓<br>Execute the process using the CRO file.<br> ↓ 860<li><code>pModule->DoFinalize()</code><br> ↓ 861<li><code>pModule->Unload()</code><br> ↓ 862<li>Free memory for the CRO file.<br> ↓ 863<li><code>pRr->Unregister()</code><br> ↓ 864<li>Free memory for the CRR file.<br> ↓ 865<li><code>nn::ro::Finalize()</code><br> ↓ 866<li>Free memory for the CRS file.<br> ↓ 867</ol> 868 869<P> 870 If you use multiple CRO files at the same time, simply repeat steps 5 to 7 as many times as necessary. If you want to load and use another CRO file after freeing the first, continue to step 10, and then return to step 5. 871</P> 872<P> 873Normally, you perform up to step 4 when the application starts, and 11 and beyond when it exits. You only perform steps 5 to 10 as appropriate when the application is running. 874</P> 875<P> 876The following sections describe each of these steps in detail. 877</P> 878 879<H3>Loading the CRS File and Initializing the <CODE>ro</CODE> Library</H3> 880<P> 881You must first load the CRS file into memory (such as from ROM-FS), and then call <a href="../../api/nn/ro/Initialize.html"><code>nn::ro::Initialize</code></a> with this as the argument. 882</P> 883<PRE> 884const wchar_t* crsPath = L"rom:/static.crs"; 885 886size_t crsSize = GetFileSize(crsPath); 887void* pCrs = AllocateMemory(crsSize, 0x1000); 888 889LoadFile(pCrs, crsPath, crsSize); 890<span class="here">nn::ro::Initialize(pCrs, crsSize);</span> 891</PRE> 892<P> 893CRS files and static modules have a one-to-one relationship; there can only be one of them per static module. Similarly, the CRS file of one static module is different from the CRS file of another. A single application never has more than one CRS file, and applications never choose which CRS file to load. 894</P> 895 896<H3>Registering CRR Files</H3> 897<P> 898You must first load the CRR file into memory (such as from ROM-FS), and then call <a href="../../api/nn/ro/RegisterList.html"><code>nn::ro::RegisterList</code></a> with this as the argument. 899</P> 900<PRE> 901const wchar_t* crrPath = L"rom:/.crr/static.crr"; 902 903size_t crrSize = GetFileSize(crrPath); 904void* pCrr = AllocateMemory(crrSize, 0x1000); 905 906LoadFile(pCrr, crrPath, crrSize); 907nn::ro::RegistrationList* pList = <span class="here">nn::ro::RegisterList(pCrr, crrSize);</span> 908</PRE> 909<P> 910A CRR file contains information about multiple CRO files. Before loading a CRO file, you must register the CRR file that contains the information about it. Ordinarily, you create a single CRR file containing the information for all CRO files that the application uses. It is normally sufficient to register just that one file. Use multiple CRR files if you want to also optimize the memory used by CRR files, or if you will be distributing additional programs. 911</P> 912 913<H3>Loading the CRO File</H3> 914<P> 915Load the CRO file, which is the actual dynamic module. Load the CRO file into memory (such as from ROM-FS), and then pass that as an argument to <a href="../../api/nn/ro/LoadModule.html"><code>nn::ro::LoadModule</code></a>. You must pass to <code>LoadModule</code> a memory area for the buffer required separately by the CRO file. Pass the CRO object as an argument to <a href="../../api/nn/ro/GetSizeInfo.html"><code>nn::ro::GetSizeInfo</code></a> to get the size of the buffer required by the CRO file. 916</P> 917<P> 918 After <code>LoadModule</code> succeeds, you must call <a href="../../api/nn/ro/Module/DoInitialize.html"><code>nn::ro::Module::DoInitialize</code></a> on the value returned by <code>LoadModule</code> before using the module. 919</P> 920<PRE> 921const wchar_t* croPath = L"rom:/module1.cro"; 922 923size_t croSize = GetFileSize(croPath); 924void* pCro = AllocateMemory(croSize, 0x1000); 925 926LoadFile(pCro, croPath, croSize); 927 928nn::ro::SizeInfo sizeInfo; 929<span class="here">nn::ro::GetSizeInfo(&sizeInfo, pCro);</span> 930 931void* pBuffer = AllocateMemory(sizeInfo.bufferSize, 8); 932nn::ro::Module* pModule = <span class="here">nn::ro::LoadModule( 933 pCro, croSize, pBuffer, sizeInfo.bufferSize);</span> 934 935<span class="here">pModule->DoInitialize();</span> 936</PRE> 937<P> 938 <code>DoInitialize</code> builds global objects. If two modules reference each other in the global-objects building stage, first perform the steps up to <code>LoadModule</code> for each module, and then call <code>DoInitialize</code> after both calls to <code>LoadModule</code> complete. 939</P> 940 941<H3>Using CRO Files</H3> 942<P> 943You have now resolved the references to the CRO file, and can call functions and read and write the variables defined in it. However, this does not necessarily mean that all the references by the loaded CRO file to other modules have been resolved. The other CRO modules that this one references may not have been loaded yet, or the symbols that it references may not have been defined or exported at all.<br> You can use the <a href="../../api/nn/ro/Module/IsAllSymbolResolved.html"><code>nn::ro::Module::IsAllSymbolResolved</code></a> function to determine whether all references to other modules by the CRO file you've loaded are resolved. 944</P> 945<P> 946Although references are resolved automatically, you can also get pointers manually. To get a pointer to a function or variable manually, use <a href="../../api/nn/ro/GetPointer.html"><code>nn::ro::GetPointer</code></a> or <a href="../../api/nn/ro/Module/GetPointer.html"><code>nn::ro::Module::GetPointer</code></a>. 947</P> 948<PRE> 949// Get a pointer to a function manually, and call it. 950int (*pFunc)(int) = <span class="here">pModule->GetPointer<void (*)(int)>("TestFunc");</span> 951int ret = pFunc(0x1234); 952 953// Get a pointer to a variable manually, and read and write it. 954int& var = *<span class="here">pModule->GetPointer<int*>("g_Variable");</span> 955NN_LOG("%d\n", var); 956var = ret; 957</PRE> 958 959 960<H3>Releasing CRO Files</H3> 961<P> 962 To release the memory used by a CRO object, call <a href="../../api/nn/ro/Module/DoFinalize.html"><code>nn::ro::Module::DoFinalize</code></a> and <a href="../../api/nn/ro/Module/Unload.html"><code>nn::ro::Module::Unload</code></a> on the value returned by <code>LoadModule</code>. 963</P> 964<PRE> 965<span class="here">pModule->DoFinalize();</span> 966<span class="here">pModule->Unload();</span> 967 968FreeMemory(pBuffer); 969FreeMemory(pCro); 970</PRE> 971<P> 972Under some conditions, you can call <code>LoadModule</code> again for the CRO object in the freed memory area, and use it again. For more information, see <a href="#reuse_cro">Reusing CRO Objects</a>. 973</P> 974 975<H3>Releasing CRR Files</H3> 976<P> 977 To release the memory used by a CRR object, call <a href="../../api/nn/ro/RegistrationList/Unregister.html"><code>nn::ro::RegistrationList::Unregister</code></a> on the value returned by <code>RegisterList</code>. 978</P> 979<PRE> 980<span class="here">pList->Unregister();</span> 981 982FreeMemory(pCrr); 983</PRE> 984 985<H3>Releasing CRS Files</H3> 986<P> 987 To release the memory area used by a CRS object, call <a href="../../api/nn/ro/Finalize.html"><code>nn::ro::Finalize</code></a>. 988</P> 989<PRE> 990<span class="here">nn::ro::Finalize();</span> 991 992FreeMemory(pCrs); 993</PRE> 994<P> 995Calling <code>nn::ro::Finalize</code> enables you to free the memory for the CRS object in addition to all CRR and CRO objects. 996</P> 997 998 999 1000 1001<h2>Debugging</h2> 1002<P> 1003 A <CODE>CRO</CODE> object can be used to debug source code in the debugger. You must include debugging information in the <CODE>CRR</CODE> object to debug source code. 1004</P> 1005<P> 1006For information about including debugging information in a <CODE>CRR</CODE> object, see <a href="BuildSystemManualForDll.html">CTR-SDK Build System Manual (for DLLs)</a> and <a href="BuildSystemDevelopmentGuideForDll.html">Guide to Developing a Build System (for DLLs)</a>. 1007</P> 1008 1009 1010 1011<h2><a name="other_feature">Special Uses</a></h2> 1012 1013<h3><a name="explicit_import_export">Explicit Imports and Exports</a></h3> 1014<p> 1015 Explicit imports and exports are mainly used in combination to enable use of plug-in type DLLs. 1016</p> 1017 1018<H4>Explicit Imports</H4> 1019<P> 1020 To explicitly import a symbol, add <CODE>NN_DLL_IMPORT</CODE> to the beginning of the function or variable declaration. 1021</P> 1022<PRE> 1023extern NN_DLL_IMPORT int g_Variable; 1024 1025extern NN_DLL_IMPORT void Function(); 1026</PRE> 1027<P> 1028An explicitly imported symbol does not generate an error, even if this definition cannot be found at link time by the linker. <br> An explicitly exported symbol is not automatically imported, so you need to either explicitly import the symbol or get the pointer manually. 1029</P> 1030 1031 1032<H4>Explicit Exports</H4> 1033<P> 1034 To explicitly export a symbol, add <CODE>NN_DLL_EXPORT</CODE> to the beginning of the function or variable declaration. 1035</P> 1036<PRE> 1037NN_DLL_EXPORT int g_Variable; 1038 1039NN_DLL_EXPORT void Function() 1040{ 1041 ... (omitted) ... 1042} 1043</PRE> 1044<P> 1045Explicitly exported symbols are exported. If explicit exports are used in a dynamic module, dead-code stripping does not remove the symbols, even if they are not referenced in the module. 1046</P> 1047<P> 1048Defining variables in multiple modules is equivalent to defining them in a static module (see <a href="#vague_linkage">Handling for Overloaded Symbols</a>). However, variables exported explicitly in any module are not included. In short, they are treated as separate variables that have their own separate memory regions in each module. 1049</P> 1050 1051 1052<h3><a name="special_func">Special Functions</a></h3> 1053<P> 1054Some of the names exported by a DLL are handled in a special way. There are three such names: <code>nnroProlog</code>, <code>nnroEpilog</code>, and <code>nnroUnresolved</code>. If a function with one of these names is defined in a DLL and exported, it is handled as follows. 1055</P> 1056<P> 1057<STRONG>Note:</STRONG> If it is a C++ function, you must add <CODE>extern "C"</CODE> to the definition. To export it, you must do so explicitly. 1058</P> 1059 1060<h4><code>nnroProlog</code></h4> 1061<P> 1062If you define a function with the name <code>nnroProlog</code> in a CRO file, <code>nnroProlog</code> is called when <a href="../../api/nn/ro/Module/DoInitialize.html"><code>nn::ro::Module::DoInitialize</code></a> is called on that CRO file. This enables you to implement initialization unique to that DLL. 1063</P> 1064<P> 1065 <code>nnroProlog</code> is called after <code>DoInitialize</code> has completed all initialization steps, including building global objects. 1066</P> 1067<PRE> 1068extern "C" NN_DLL_EXPORT void nnroProlog() 1069{ 1070 ... (omitted) ... 1071} 1072</PRE> 1073 1074 1075<h4><code>nnroEpilog</code></h4> 1076<P> 1077If you define a function with the name <code>nnroEpilog</code> in a CRO file and export it, <code>nnroProlog</code> is called when <a href="../../api/nn/ro/Module/DoFinalize.html"><code>nn::ro::Module::DoFinalize</code></a> is called on that CRO file. This enables you to implement finalization unique to that DLL. 1078</P> 1079<P> 1080 <code>nnroEpilog</code> is called before <code>DoFinalize</code> does any finalization, such as freeing global objects. 1081</P> 1082<PRE> 1083extern "C" NN_DLL_EXPORT void nnroEpilog() 1084{ 1085 ... (omitted) ... 1086} 1087</PRE> 1088 1089 1090<h4><a name="nnroUnresolved"><CODE>nnroUnresolved</CODE></a></h4> 1091<P> 1092If you define a function named <code>nnroUnresolved</code> in your CRO file and export it, unresolved references from this file are linked to this function. If you do so, <code>nnroUnresolved</code> are called when a function is called, and the DLL in which it is defined has not been loaded. 1093</P> 1094<PRE> 1095extern "C" NN_DLL_EXPORT void nnroUnresolved() 1096{ 1097 ... (omitted) ... 1098} 1099</PRE> 1100<P> 1101This particular function can also be used in static modules. However, there is a limitation. It stops working if references, after they have been resolved, are reverted to the unresolved state. 1102</P> 1103 1104 1105 1106 1107<h3><a name="free_unused">Freeing Unneeded Memory</a></h3> 1108<P> 1109In addition to executable code, a CRO file contains information about symbols referenced from other modules, and symbols exported to other modules. If you know that this information will not be needed after the CRO file is loaded, you can free it and use it for other purposes after <CODE>LoadModule</CODE> by specifying a <CODE>fixLevel</CODE> argument to <a href="../../api/nn/ro/LoadModule.html"><code>nn::ro::LoadModule</code></a>. This can greatly reduce your memory usage, particularly when the module references or exports a large number of symbols. Conversely, if the module does not have much of this information, freeing it may not increase the available memory size at all. 1110</P> 1111<PRE> 1112const wchar_t* croPath = L"rom:/module1.cro"; 1113 1114size_t croSize = GetFileSize(croPath); 1115void* pCro = AllocateMemory(croSize, 0x1000); 1116 1117LoadFile(pCro, croPath, croSize); 1118 1119nn::ro::SizeInfo sizeInfo; 1120nn::ro::GetSizeInfo(&sizeInfo, pCro); 1121 1122void* pBuffer = AllocateMemory(sizeInfo.bufferSize, 8); 1123nn::ro::Module* pModule = nn::ro::LoadModule( 1124 pCro, croSize, pBuffer, sizeInfo.bufferSize, 1125 true, <span class="here">nn::ro::FIX_LEVEL_3</span>); 1126 1127<span class="here">void* pFreeBuffer = reinterpret_cast<void*>(sizeInfo.fix3End)</span>; 1128<span class="here">size_t freeSize = croSize - (sizeInfo.fix3End - reinterpret_cast<uptr>(pCro))</span>; 1129</PRE> 1130<P> 1131This code made the <code>freeSize</code> portion of <code>pFreeBuffer</code> available. 1132</P> 1133<P> 1134</P> 1135<h3><a name="reuse_cro">Reusing CRO Objects</a></h3> 1136<P> 1137Normally, you cannot reuse a CRO module you passed to <a href="../../api/nn/ro/LoadModule.html"><code>nn::ro::LoadModule</code></a> after you have called <a href="../../api/nn/ro/Module/Unload.html"><code>nn::ro::Module::Unload</code></a> on it. However, you can reuse them if the following conditions are met. 1138</P> 1139<ol> 1140<li>You use <code>FIX_LEVEL_0</code>. 1141<li>It does not use initial values for static variables. 1142</ol> 1143<P> 1144The following practices enable you to satisfy condition 2 in your implementation: 1145</P> 1146<ul> 1147<li>Do not use static variables. 1148<li>Initialize all static variables by using the <code>nnroProlog</code> function. 1149</ul> 1150<P> 1151 1152</P> 1153<PRE> 1154const wchar_t* croPath = L"rom:/module1.cro"; 1155 1156size_t croSize = GetFileSize(croPath); 1157void* pCro = AllocateMemory(croSize, 0x1000); 1158 1159LoadFile(pCro, croPath, croSize); 1160 1161nn::ro::SizeInfo sizeInfo; 1162nn::ro::GetSizeInfo(&sizeInfo, pCro); 1163 1164void* pBuffer = AllocateMemory(sizeInfo.bufferSize, 8); 1165 1166// Loaded the first time. 1167nn::ro::Module* pModule = nn::ro::LoadModule( 1168 pCro, croSize, pBuffer, sizeInfo.bufferSize, 1169 true, <span class="here">nn::ro::FIX_LEVEL_0</span>); 1170pModule->DoInitialize(); 1171 1172 ... (use cro module) ... 1173 1174// Free it. 1175pModule->DoFinalize(); 1176pModule->Unload(); 1177 1178// You can reload it without reading it from memory again. 1179<span class="here">pModule = nn::ro::LoadModule(pCro, croSize, pBuffer, sizeInfo.bufferSize);</span> 1180<span class="here">pModule->DoInitialize();</span> 1181</PRE> 1182 1183 1184 1185 1186 1187<H2>Revision History</H2> 1188<dl class="history"> 1189 <dt>2012/06/22</dt> 1190 <dd> 1191Added a link to <I>Guide to Developing a Build System (for High-Level DLLs)</I>.<br/> 1192 </dd> 1193 1194 <dt>2012/04/23</dt> 1195 <dd> 1196Added the Handling for Overloaded Symbols section.<br/>Updated the description of handling of static variables in the Restrictions section.<br/>Added the description about support for multiple definitions in Creating the Source Code in the Creating Static Modules section.<br/>Added the relationship with multiple definitions in the Explicit Imports and Exports section.<br/> 1197 </dd> 1198 1199 <dt>2012/02/27</dt> 1200 <dd> 1201Added specific descriptions to the Restrictions section about standard C functions and similar functions. 1202 </dd> 1203 1204 <dt>2012/01/23</dt> 1205 <dd> 1206Added a note to the Restrictions section that static variables cannot be properly handled. 1207 </dd> 1208 1209 <dt>2011/12/12</dt> 1210 <dd> 1211Added the Restrictions item to the section Features and Limitations of the RO Format, and moved the information about this topic to this item.<br>Clarified in Restrictions that the SDK's static libraries must not be made and used as DLLs.<br>Added the section Using Static Libraries.<br>Added the section Creating Static Modules.<br>Updated the section Special Functions to reflect the fact that <CODE>nnroUnresolved</CODE> can be used in static modules.<br>Touched up the section Explicit Imports and Exports.<br>Corrected the Explicit Imports example.<br> 1212 </dd> 1213 1214 <dt>2011/09/26</dt> 1215 <dd> 1216Updated the Debugging section to reflect the debugging source code. Added the Revision History section. 1217 </dd> 1218 1219 <dt>2011/08/03</dt> 1220 <dd> 1221 Initial version. 1222 </dd> 1223</dl> 1224 1225 1226<div class="footer"><span>DLL Manual</span></div> 1227 1228 <hr><p>CTR-06-0201-002-I<br>CONFIDENTIAL</p></body> 1229</HTML> 1230