1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<HTML LANG="ja"> 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><a href="BuildSystemManualForDll.html" target="_parent">CTR-SDK Build System Manual (for DLLs)</a> 423 <li>Information about developing your own build system:<br><a href="BuildSystemDevelopmentGuideForDll.html" target="_parent">Guide to Developing a Build System (for DLLs)</a> 424<li>Information about developing a more sophisticated build system:<br><a href="BuildSystemDevelopmentGuideForDllAdvanced.html" target="_parent">Guide to Developing a Build System (for High-Level DLLs)</a> 425</ul> 426 427<P> 428 This document assumes basic knowledge of <CODE>CTR-SDK</CODE> terminology. See <a href="../Glossary/Glossary.html" target="_parent">CTR-SDK Terminology</a> for a glossary of basic CTR-SDK terms. 429</P> 430 431<H3>Notation Used in This Document</H3> 432<P> 433 This document sometimes puts content in colored boxes like the one below to indicate that it is sample source code. 434</P> 435<pre> 436nn::ro::Initialize(pCrs, crsSize); 437</pre> 438 439<P> 440 Sample source code uses the following user-defined functions in order to make the code easier to understand. You must implement processing equivalent to these functions in your application. 441</P> 442<dl> 443 <dt>s64 GetFileSize(const wchar_t* path) 444 <dd> 445 Returns the size of the file specified by <SPAN class="argument">path</SPAN>. 446 447 <dt>void* AllocateMemory(size_t size, int alignment) 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>void LoadFile(void* pBuffer, const wchar_t* path, size_t size) 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> 480 The main application module, which contains <CODE>nnMain</CODE>. This 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> 496 Use a symbol from another module. This refers to calling a function defined in another module, or reading/writing a variable defined in another module. 497 498 <dt>Resolve 499 <dd> 500 Make the symbol being referenced available. It determines the address of a symbol so that a function can be called, or a variable read/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>Export 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 520 <dt><CODE>ro</CODE> 521 <dd> 522 A format for implementing DLLs provided by the CTR-SDK. 523 524 <dt>CRO Files 525 <dd> 526 The dynamic-module file format used by <CODE>ro</CODE>. 527 528 <dt>CRR Files 529 <dd> 530 A file storing DLL registration information. It can store information for one or more CRO files. 531 532 <dt><CODE>cro.rlt</CODE> 533 <dd> 534 A file that stores DLL registration information. This file stores information for one CRO file. It is converted into a CRR file for use. 535 536 <dt><CODE>edit</CODE> 537 <dd> 538 A steering file used by the <CODE>ARMCC</CODE> linker. 539 540 <dt>CRS Files 541 <dd> 542 A file storing information about a static module. 543 544 <dt><CODE>xrl</CODE> 545 <dd> 546 A file storing export/reference symbol information for a module. 547 548 <dt><CODE>uae</CODE> 549 <dd> 550 A command-line option file specified to the <CODE>ARMCC</CODE> linker. 551 552 <dt><CODE>ro</CODE> library 553 <dd> 554 The <a href="../../api/nn/ro/Overview.html">nn::ro namespace</a> section of the API provided by the CTR-SDK. It is a collection of functions for using DLLs. 555 556 <dt> 557 <dd> 558 559 560 561</dl> 562 563 564 565 566 567 568<H2>DLLs</H2> 569 570<H3>Static and Dynamic Modules</H3> 571<P> 572 If an application does not use dynamic modules, then all its executable code is collected into a single file. 573 574 When an application starts, all 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. 575 576 The executable code that is loaded upon startup is called the "static module." 577</P> 578<P> 579 Meanwhile, if the application uses dynamic modules, then it can split up its executable code into multiple modules. 580 581 When the application starts, only the static module is loaded into memory. The static module is then able to load the dynamic modules, thus running executable code including dynamic modules that can be loaded into and released from memory during program execution. 582</P> 583 584 585 586<H3>What You Can Do with a DLL</H3> 587 588<H4>Conserve Memory</H4> 589<P> 590 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. 591</P> 592<P> 593 For 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 will reduce your application's memory footprint by the size of the other mode. 594</P> 595 596<H4>Shorten Startup Time</H4> 597<P> 598 When your application is launched, it starts running after all of its static modules have been loaded into memory. Thus the time it takes from the application's launch 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. 599</P> 600 601<!-- <H4>追加プログラムの配信</H4> <P> DLL を配信することで、販売後のアプリケーションにプログラムを追加することができます。 </P> --> 602 603 604<h3>Features and Limitations of the <CODE>ro</CODE> Format</h3> 605<P> 606The DLL mechanism provided by the CTR-SDK is called "ro." 607</P> 608 609<h4>Features</h4> 610<P> 611 The <CODE>ro</CODE> format features the following differences from other DLL implementations. 612</P> 613 614<ul> 615<li>Thee 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. 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> for information about specifying export types. 616 617<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 obtain pointers to symbols manually. 618 619<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. 620 621<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. 622 623<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. 624 625<li>Support for automating imports and exports<br>Although this is not a feature of the <CODE>ro</CODE> 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. 626</ul> 627 628<h4>Upper Limit</h4> 629<P> 630 The limitations of the <CODE>ro</CODE> format are as follows. 631</P> 632<ul> 633<li>Each module can export no more than 65,535 symbols by name. 634<li>The maximum length of a symbol that can be exported by name is 8,192 characters. 635</ul> 636 637<h4><a name="restriction">Restrictions</a></h4> 638<P> 639 The <CODE>ro</CODE> format has the following restrictions: 640</P> 641<ul> 642<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 details, see <a href="#vague_linkage">Handling of Symbols with Multiple Definitions</a>. 643<li>You cannot include symbols belonging to the C Runtime (CRT) in dynamic modules. These are always included in static modules. The CRT includes standard C functions, as well as <CODE>new</CODE>, <CODE>delete</CODE>, and other language features implemented as internal function calls, such as integer division and 64-bit arithmetic. 644<li>You cannot define static variables or constants specifying an alignment greater than 8 bytes. Alignment restrictions greater than 8 bytes are ignored. 645<li>Behavior 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. 646</ul> 647<P> 648 In the <CODE>ro</CODE> format, you can make and use any static library (.a) 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. 649</P> 650<P> 651 The static libraries (.a) provided in the SDK must not be made and used as DLLs. That is prohibited. 652</P> 653 654 655<h3><CODE>ro</CODE> File Structure</h3> 656<P> 657 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. 658</P> 659 660<h4>CRS Files</h4> 661<P> 662 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. 663</P> 664 665<h4>CRR Files</h4> 666<P> 667 A CRR file contains CRO management information. It also contains information necessary for debugging DLLs. 668</P> 669<P> 670 CRR files have an important limitation: they must be stored on the ROM-FS, directly under the ".crr" directory, which is in turn directly under the ROM-FS root directory (if the ROM-FS root directory is <code>/</code>, this directory will be <code>/.crr</code>). The <code>.crr</code> directory must not contain any file other than the CRR file. 671</P> 672 673<h4>CRO Files</h4> 674<P> 675 A CRO file is a dynamic module. It stores executable code and information necessary to resolve symbols between the application's various modules. 676</P> 677 678 679 680 681 682 683 684<H2>Creating Dynamic Modules</H2> 685 686<H3>Creating the Source Code</H3> 687<P> 688 There 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 things you need to do in order to call functions and reference variables across modules are to share headers and code the calls and references. 689</P> 690<P> 691 To read about the restrictions on dynamic modules, see <a href="#restriction">Restrictions.</a> 692</P> 693<P> 694 You must add extra code to use DLL features. See <a href="#other_feature">Special Uses</a> for details. 695</P> 696 697 698 699<H3>Building DLLs</H3> 700<P> 701 See <a href="BuildSystemManualForDll.html" target="_parent">CTR-SDK Build System Manual (for DLLs)</a> if you will be using the SDK's build system. If you will be developing your own build system, see <a href="BuildSystemDevelopmentGuideForDll.html" target="_parent">Guide to Developing a Build System (for DLLs)</a>. 702</P> 703 704 705 706<H3><a name="choose_type">Selecting the Export Type</a></H3> 707<P> 708 The <CODE>ro</CODE> format has three export types. You must select which export types to use when you create your CRO file. The table below shows the differences between the various export types. 709</P> 710<table> 711<tr><th><th>Name<th>Index<th>Offset 712<tr><th>Size of referencing CRO file<td>Large<td>Small<td>Small 713<tr><th>Size of exporting CRO file<td>Large<td>Small<td>0 714<tr><th>Time required by <CODE>LoadModule</CODE><td>Long<td>Medium<td>Short 715<tr><th>Getting pointer manually<td>Possible<td>Possible<td>Impossible 716<tr><th>Creating referencing module first<td>Possible<td>Impossible<td>Impossible 717<tr><th>Build steps<td>Normal<td>Normal<td>Many 718</table> 719<P> 720 <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. 721</P> 722<P> 723 Normally, 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, you will choose <CODE>index</CODE> or <CODE>name</CODE>, depending on your needs. 724</P> 725 726<H3>Using Static Libraries</H3> 727<P> 728 Static libraries can be embedded into dynamic modules. However, in addition to the <a href="#restriction"><CODE>ro</CODE> restrictions </a>, you should also note the following precaution: 729</P> 730<ul> 731<li><b>Do not embed the same static library into multiple DLLs. </b><br>If you embed the same static library into multiple DLLs, then there will be multiple global variables, where there should only be one. So 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 will be as if the library is not conducting mutual exclusion, even though it is treating the mutex correctly. In this case, sometimes a bug will arise and sometimes it will not (depending on the timing) so debugging will be difficult. Moreover, since the coding will be correct in the source code, it will be extremely difficult to find the bug. 732</ul> 733 734 735 736 737<H2>Creating Static Modules</H2> 738<H3>Creating the Source Code</H3> 739<P> 740 Some variables require special treatment. For more information, see <a href="#vague_linkage">Handling Symbols with Multiple Definitions</a>.<br/> Other than symbols with multiple definitions, there is nothing special that must be done to reference DLL functions and variables. You simply share headers and reference the normal way. 741</P> 742<P> 743 In the <CODE>ro</CODE> format, the management of DLLs is left entirely up to the application, so to prepare memory for use by DLLs and to load DLLs you need to implement everything with code in the application. For details, see <a href="#use_dll">Using DLLs</a>. 744</P> 745<P> 746 In addition, you need to add extra code to use DLL features. See <a href="#other_feature">Special Uses</a> for details. 747</P> 748 749 750 751<H3>Building</H3> 752<P> 753 See <a href="BuildSystemManualForDll.html" target="_parent">CTR-SDK Build System Manual (for DLLs)</a> if you will be using the SDK's build system. If you will be developing your own build system, see <a href="BuildSystemDevelopmentGuideForDll.html" target="_parent">Guide to Developing a Build System (for DLLs)</a>. 754</P> 755 756 757 758<H3>Selecting the Export Type</H3> 759<P> 760You can select the export type, so 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. 761</P> 762 763 764 765 766 767<H2><a name="vague_linkage">Handling of Symbols with Multiple Definitions</a></H2> 768<P> 769 Symbols with multiple definitions require special treatment. 770</P> 771 772<H3>Symbols with Multiple Definitions in C++</H3> 773<P> 774 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. 775</P> 776<ul> 777 <li>Template instances 778 <li>Inline functions that were not inlined. 779 <li>Template class class member variables 780 <li>Static local variables in inline functions 781 <li>Type information. 782 <li>Virtual tables 783</ul> 784<P> 785 Symbols for these are merged appropriately by the linker during linking, and an adjustment is made so that all the symbols become one in the overall program. 786</P> 787 788<H3>Handling of Symbols with Multiple Definitions in <CODE>ro</CODE></H3> 789<P> 790 Because the symbols are merged by a linker, they must be merged in each module. Also, because plug-in type use is supported in <CODE>ro</CODE>, multiple modules are permitted to contain the same symbol. As a result, an instance of the symbols for the elements listed above exists in each module that is referenced. 791</P> 792<P> 793 However, because usually symbols that represent variables among the elements listed above 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. 794</P> 795<P> 796 Processes for variables and elements other than variables are separated in <CODE>ro</CODE> in order to handle both situations. 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. 797</P> 798 799<H3>Support for Symbols with Multiple Definitions</H3> 800<P> 801 As described above, when symbols that represent variables are defined in multiple modules, <CODE>ro</CODE> assumes that those symbol definitions are in the static module and then references them in the static module. 802</P> 803<P> 804 If a definition that is referenced is not in the static module, an error will occur 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. 805</P> 806<P> 807 If multiple definitions are not created (intentionally or accidentally), support will be necessary for the following. 808</P> 809<ul> 810 <li>Class member variables for the template class. 811 <li>Static local variables in inline functions. 812</ul> 813<P> 814 The definitions of symbols for the above are created in object files created from the source files that referenced those symbols. So, 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 by using the variable represented by the symbol.<br/> <a href="../../api/nn_util/NN_UTIL_REFER_SYMBOL.html"><code>NN_UTIL_REFER_SYMBOL</code></a> can be used for this purpose. 815</P> 816<P> 817 For example, when a header such as the following is used, the conditions described above 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> in the dynamic modules will cause an error at build time. 818</P> 819<P> 820 Header<br/> (Code from the very beginning) 821</P> 822<PRE> 823... (omitted) ... 824 825template <class T> 826class Singleton 827{ 828public: 829 static T& GetInstance() { return *ms_pInstance; } 830 831protected: 832 Singleton() { ms_pInstance = static_cast<T*>(this); } 833 ~Singleton() { ms_pInstance = NULL; } 834 835private: 836 static T* ms_pInstance; 837}; 838 839template <class T> T* Singleton <T>::ms_pInstance = NULL; 840 841class S : public Singleton<S> 842{ 843}; 844 845... (omitted) ... 846</PRE> 847<P> 848 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. 849</P> 850<P> 851 Any source files that are used in static modules <br/> (code added for <CODE>ro</CODE> support) 852</P> 853<PRE> 854... (omitted) ... 855 856void DummyReference() 857{ 858 <span class="here">NN_UTIL_REFER_SYMBOL(S::GetInstance);</span> 859} 860</PRE> 861 862 863 864 865 866<H2><a name="use_dll">Using DLLs</a></H2> 867 868<H3>Basic Sequence</H3> 869<P> 870 The list below shows the sequence from loading a single CRO file, to using it, and then freeing all memory. 871</P> 872 873<ol> 874<li>Load CRS file into memory<br> ↓ 875<li><code>nn::ro::Initialize(crs)</code><br> ↓ 876<li>Load CRR file into memory<br> ↓ 877<li><code>nn::ro::RegisterList(crr)</code><br> ↓ 878<li>Load CRO file into memory<br> ↓ 879<li><code>nn::ro::LoadModule(cro)</code><br> ↓ 880<li><code>pModule->DoInitialize()</code><br> ↓<br>Execute process using CRO file<br> ↓ 881<li><code>pModule->DoFinalize()</code><br> ↓ 882<li><code>pModule->Unload()</code><br> ↓ 883<li>Free memory for CRO file<br> ↓ 884<li><code>pRr->Unregister()</code><br> ↓ 885<li>Free memory for CRR file<br> ↓ 886<li><code>nn::ro::Finalize()</code><br> ↓ 887<li>Free memory for CRS file<br> ↓ 888</ol> 889 890<P> 891 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. 892</P> 893<P> 894 Normally, you will perform up to step 4 when the application starts, and 11 and beyond when it exits. You will only perform steps 5 to 10 as appropriate when the application is running. 895</P> 896<P> 897 Below, each of these steps is described in detail. 898</P> 899 900<H3>Loading CRS File and Initializing <CODE>ro</CODE> Library</H3> 901<P> 902 You must first load the CRS file into memory (e.g., from ROM-FS), and then call <a href="../../api/nn/ro/Initialize.html"><code>nn::ro::Initialize</code></a> with this as the argument. 903</P> 904<PRE> 905const wchar_t* crsPath = L"rom:/static.crs"; 906 907size_t crsSize = GetFileSize(crsPath); 908void* pCrs = AllocateMemory(crsSize, 0x1000); 909 910LoadFile(pCrs, crsPath, crsSize); 911<span class="here">nn::ro::Initialize(pCrs, crsSize); 912</span></PRE> 913<P> 914 There is a one-to-one relationship between CRS files and static modules; there can only be one of them per static module. Similarly, the CRS file of one static module will be different from the CRS file of another. Therefore, a single application will never have more than one CRS file, and applications never choose which CRS file to load. 915</P> 916 917<H3>Registering CRR Files</H3> 918<P> 919 You must first load the CRR file into memory (e.g., from ROM-FS), and then call <a href="../../api/nn/ro/RegisterList.html"><code>nn::ro::RegisterList</code></a> with this as the argument. 920</P> 921<PRE> 922const wchar_t* crrPath = L"rom:/.crr/static.crr"; 923 924size_t crrSize = GetFileSize(crrPath); 925void* pCrr = AllocateMemory(crrSize, 0x1000); 926 927LoadFile(pCrr, crrPath, crrSize); 928nn::ro::RegistrationList* pList = <span class="here">nn::ro::RegisterList(pCrr, crrSize); 929</span></PRE> 930<P> 931 A 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 will create a single CRR file containing the information for all CRO files that the application will use. It is therefore 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. 932</P> 933 934<H3>Loading the CRO File</H3> 935<P> 936 Load the CRO file, which is the actual dynamic module. Load the CRO file into memory (e.g., 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. 937</P> 938<P> 939 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. 940</P> 941<PRE> 942const wchar_t* croPath = L"rom:/module1.cro"; 943 944size_t croSize = GetFileSize(croPath); 945void* pCro = AllocateMemory(croSize, 0x1000); 946 947LoadFile(pCro, croPath, croSize); 948 949nn::ro::SizeInfo sizeInfo; 950<span class="here">nn::ro::GetSizeInfo(&sizeInfo, pCro); 951 952void* pBuffer = AllocateMemory(sizeInfo.bufferSize, 8); 953nn::ro::Module* pModule = <span class="here">nn::ro::LoadModule( 954 pCro, croSize, pBuffer, sizeInfo.bufferSize);</span> 955 956<span class="here">pModule->DoInitialize();</span> 957</span></PRE> 958<P> 959 <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. 960</P> 961 962<H3>Using CRO Files</H3> 963<P> 964 You have now resolved the references to the CRO file, and it is possible to call functions and read/write 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. 965</P> 966<P> 967 Although references are resolved automatically, you can also obtain 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>. 968</P> 969<PRE> 970// Get a pointer to a function manually, and call it 971int (*pFunc)(int) = <span class="here">pModule->GetPointer<void (*)(int)>("TestFunc");</span> 972int ret = pFunc(0x1234); 973 974// Get a pointer to a variable manually, and read/write it 975int& var = *<span class="here">pModule->GetPointer<int*>("g_Variable");</span> 976NN_LOG("%d\n", var); 977var = ret; 978</PRE> 979 980 981<H3>Releasing CRO Files</H3> 982<P> 983 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>. 984</P> 985<PRE> 986<span class="here">pModule->DoFinalize(); 987<span class="here">pModule->Unload();</span> 988 989FreeMemory(pBuffer); 990FreeMemory(pCro); 991</span></PRE> 992<P> 993 Under certain conditions, you can call <code>LoadModule</code> again for the CRO object in the freed memory area, and use it again. See <a href="#reuse_cro">Reusing CRO Objects</a> for details. 994</P> 995 996<H3>Releasing CRR Files</H3> 997<P> 998 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>. 999</P> 1000<PRE> 1001<span class="here">pList->Unregister(); 1002 1003FreeMemory(pCrr); 1004</span></PRE> 1005 1006<H3>Releasing CRS Files</H3> 1007<P> 1008 To release the memory area used by a CRS object, call <a href="../../api/nn/ro/Finalize.html"><code>nn::ro::Finalize</code></a>. 1009</P> 1010<PRE> 1011<span class="here">nn::ro::Finalize(); 1012 1013FreeMemory(pCrs); 1014</span></PRE> 1015<P> 1016 Calling <code>nn::ro::Finalize</code> enables you to free the memory for the CRS object as well as all CRR and CRO objects. 1017</P> 1018 1019 1020 1021 1022<h2>Debug</h2> 1023<P> 1024 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. 1025</P> 1026<P> 1027 See <a href="BuildSystemManualForDll.html">CTR-SDK Build System Manual (for DLLs)</a> or <a href="BuildSystemDevelopmentGuideForDll.html">Guide to Developing a Build System (for DLLs)</a> for information about including debugging information in a <CODE>CRR</CODE> object. 1028</P> 1029 1030 1031 1032<h2><a name="other_feature">Special Uses</a></h2> 1033 1034<h3><a name="explicit_import_export">Explicit Imports and Exports</a></h3> 1035<p> 1036 Explicit imports and exports are mainly used in combination to enable use of plug-in type DLLs. 1037</p> 1038 1039<H4>Explicit Imports</H4> 1040<P> 1041 To explicitly import a symbol, add <CODE>NN_DLL_IMPORT</CODE> to the beginning of the function or variable declaration. 1042</P> 1043<PRE> 1044extern NN_DLL_IMPORT int g_Variable; 1045 1046extern NN_DLL_IMPORT void Function(); 1047</PRE> 1048<P> 1049An 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. 1050</P> 1051 1052 1053<H4>Explicit Exports</H4> 1054<P> 1055 To explicitly export a symbol, add <CODE>NN_DLL_EXPORT</CODE> to the beginning of the function or variable declaration. 1056</P> 1057<PRE> 1058NN_DLL_EXPORT int g_Variable; 1059 1060NN_DLL_EXPORT void Function() 1061{ 1062 ... (omitted) ... 1063} 1064</PRE> 1065<P> 1066 Explicitly exported symbols will be exported. If explicit exports are used in a dynamic module, dead-code stripping will not remove the symbols, even if they are not referenced in the module. 1067</P> 1068<P> 1069 When variables are defined in multiple modules, processing is performed as if the variables are defined in static modules (see <a href="#vague_linkage">Handling of Symbols with Multiple Definitions</a>). However, variables exported explicitly in any module will not be included in that processing. In short, they will be treated as separate variables that have their own separate memory regions in each module. 1070</P> 1071 1072 1073<h3><a name="special_func">Special Functions</a></h3> 1074<P> 1075 Some 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 will be handled as follows. 1076</P> 1077<P> 1078 <STRONG>Note:</STRONG> If it is a C++ function, you must add <CODE>extern "C"</CODE> to the definition. In order to export it, you must do so explicitly. 1079</P> 1080 1081<h4><code>nnroProlog</code></h4> 1082<P> 1083 If you define a function with the name <code>nnroProlog</code> in a CRO file, then <code>nnroProlog</code> will be 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. 1084</P> 1085<P> 1086 <code>nnroProlog</code> is called after <code>DoInitialize</code> has completed all initialization steps, including building global objects. 1087</P> 1088<PRE> 1089extern "C" NN_DLL_EXPORT void nnroProlog() 1090{ 1091 ... (omitted) ... 1092} 1093</PRE> 1094 1095 1096<h4><code>nnroEpilog</code></h4> 1097<P> 1098 If you define a function with the name <code>nnroEpilog</code> in a CRO file and export it, then <code>nnroProlog</code> will be 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. 1099</P> 1100<P> 1101 <code>nnroEpilog</code> is called before <code>DoFinalize</code> does any finalization, such as freeing global objects. 1102</P> 1103<PRE> 1104extern "C" NN_DLL_EXPORT void nnroEpilog() 1105{ 1106 ... (omitted) ... 1107} 1108</PRE> 1109 1110 1111<h4><a name="nnroUnresolved"><CODE>nnroUnresolved</CODE></a></h4> 1112<P> 1113 If you define a function named <code>nnroUnresolved</code> in your CRO file and export it, then unresolved references from this file will be linked to this function. If you do so, <code>nnroUnresolved</code> will be called when a function is called, and the DLL in which it is defined has not been loaded. 1114</P> 1115<PRE> 1116extern "C" NN_DLL_EXPORT void nnroUnresolved() 1117{ 1118 ... (omitted) ... 1119} 1120</PRE> 1121<P> 1122 This particular function can also be used in static modules. However, there is a limitation. It will stop working if references, once they have been resolved, are reverted to the unresolved state. 1123</P> 1124 1125 1126 1127 1128<h3><a name="free_unused">Freeing Unneeded Memory</a></h3> 1129<P> 1130 In 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, then you can free it and use it for other purposes after <CODE>LoadModule</CODE> by specifying a <SPAN class="argument">fixLevel</SPAN> 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 and/or exports a large number of symbols. Conversely, if the module does not have much of this information, then freeing it may not increase the available memory size at all. 1131</P> 1132<PRE> 1133const wchar_t* croPath = L"rom:/module1.cro"; 1134 1135size_t croSize = GetFileSize(croPath); 1136void* pCro = AllocateMemory(croSize, 0x1000); 1137 1138LoadFile(pCro, croPath, croSize); 1139 1140nn::ro::SizeInfo sizeInfo; 1141nn::ro::GetSizeInfo(&sizeInfo, pCro); 1142 1143void* pBuffer = AllocateMemory(sizeInfo.bufferSize, 8); 1144nn::ro::Module* pModule = nn::ro::LoadModule( 1145 pCro, croSize, pBuffer, sizeInfo.bufferSize, 1146 true, <span class="here">nn::ro::FIX_LEVEL_3); 1147 1148<span class="here">void* pFreeBuffer = reinterpret_cast<void*>(sizeInfo.fix3End)</span>; 1149<span class="here">size_t freeSize = croSize - (sizeInfo.fix3End - reinterpret_cast<uptr>(pCro))</span>; 1150</span></PRE> 1151<P> 1152 The code above made the <code>freeSize</code> portion of <code>pFreeBuffer</code> available. 1153</P> 1154<P> 1155</P> 1156 1157<h3><a name="reuse_cro">Reusing CRO Objects</a></h3> 1158<P> 1159 Normally, it is not possible to 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, it is possible to reuse them if the following conditions are met. 1160</P> 1161<ol> 1162<li>You use <code>FIX_LEVEL_0</code> 1163<li>It does not use initial values for static variables 1164</ol> 1165<P> 1166 Below are some ways you can satisfy condition 2 in your implementation: 1167</P> 1168<ul> 1169<li>Do not use static variables 1170<li>Initialize all static variables by using the <code>nnroProlog</code> function. 1171</ul> 1172<P> 1173 1174</P> 1175 1176<PRE> 1177const wchar_t* croPath = L"rom:/module1.cro"; 1178 1179size_t croSize = GetFileSize(croPath); 1180void* pCro = AllocateMemory(croSize, 0x1000); 1181 1182LoadFile(pCro, croPath, croSize); 1183 1184nn::ro::SizeInfo sizeInfo; 1185nn::ro::GetSizeInfo(&sizeInfo, pCro); 1186 1187void* pBuffer = AllocateMemory(sizeInfo.bufferSize, 8); 1188 1189// Loaded first time 1190nn::ro::Module* pModule = nn::ro::LoadModule( 1191 pCro, croSize, pBuffer, sizeInfo.bufferSize, 1192 true, <span class="here">nn::ro::FIX_LEVEL_0);</span> 1193pModule->DoInitialize(); 1194 1195 ... (use cro module) ... 1196 1197// Free it 1198pModule->DoFinalize(); 1199pModule->Unload(); 1200 1201// It can be reloaded without reading it from memory again 1202<span class="here">pModule = nn::ro::LoadModule(pCro, croSize, pBuffer, sizeInfo.bufferSize);</span> 1203<span class="here">pModule->DoInitialize();</span> 1204</PRE> 1205 1206 1207 1208 1209 1210<H2>Revision History</H2> 1211<dl class="history"> 1212 <dt>2012/06/22</dt> 1213 <dd> 1214Added a link to <I>Guide to Developing a Build System (for High-Level DLLs)</I>.<br/> 1215 </dd> 1216 1217 <dt>2012/04/23</dt> 1218 <dd> 1219 Added the "Handling of Symbols with Multiple Definitions" section.<br/> Updated description of handling of static variables in <B>Restrictions</B> section.<br/> Added description about support for multiple definitions in "Creating the Source Code" in the "Creating Static Modules" section.<br/> Added relationship with multiple definitions in the "Explicit Imports and Exports" section.<br/> 1220 </dd> 1221 1222 <dt>2012/02/27</dt> 1223 <dd> 1224 Added specific descriptions to the <B>Restrictions</B> section regarding standard C functions and similar functions. 1225 </dd> 1226 1227 <dt>2012/01/23</dt> 1228 <dd> 1229 Added note to the <B>Restrictions</B> section that static variables cannot be properly handled. 1230 </dd> 1231 1232 <dt>2011/12/12</dt> 1233 <dd> 1234 Added the item "Restrictions" to the section "Features and Limitations of the <CODE>ro</CODE> 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 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> 1235 </dd> 1236 1237 <dt>2011/09/26</dt> 1238 <dd> 1239 Updated the "Debugging" section to reflect debugging source code. Added the Revision History section. 1240 </dd> 1241 1242 <dt>2011/08/03</dt> 1243 <dd> 1244 Initial version. 1245 </dd> 1246</dl> 1247 1248 1249<div class="footer"><span>DLL Manual</span></div> 1250 1251 <hr><p>CTR-06-0201-002-G<br>CONFIDENTIAL</p></body> 1252</HTML>