personal-site/out/blogs/doing-c-assignments-in-csharp.html

80 lines
6.3 KiB
HTML
Raw Normal View History

2023-07-30 23:11:02 +00:00
<head>
<title>Nicholas Orlowsky</title>
<link rel="stylesheet" href="/style.css">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
</head>
<body>
<nav>
<a href="/">[ Home ]</a>
<a href="/blog.html">[ Blog ]</a>
<a href="/projects.html">[ Projects ]</a>
<a href="/extra.html">[ Extra ]</a>
<hr/>
</nav>
<h1>Doing C assignments in C#</h1>
<p>Thanks to Arpan Dhatt for doing most of the work on this (his blog here: <a href="https://arpan.one/posts/messing-with-gradescope/">https://arpan.one/posts/messing-with-gradescope/</a>)</p>
<p>At the end, he made this comment:</p>
<blockquote>
2025-02-01 00:29:54 +00:00
<p>And so, that&#39;s the end of this post. To whom it may concern, don&#39;t try doing your C assignment in C# (you know who you are).</p>
2023-07-30 23:11:02 +00:00
</blockquote>
2025-02-01 00:29:54 +00:00
<p>The reason for this comment (besides the fact that I talk about C# a lot) is due to the fact that C# requires a runtime to be installed for it to work. This is because C# does not compile to native bytecode but rather compiles to an intermediary language (dubbed CIL by Microsoft) and is then translated &#39;Just In Time&#39; by the runtime. </p>
<p>This makes running assignments in a docker container where the runtime is not already installed considerably hard. One option we have is that we could just include the runtime in our submission. Sounds easy, right? Well it would be non-trivial to do but due to the fact that the .NET runtime is very large, I wouldn&#39;t consider this a good idea (Not to mention it&#39;s super boring). </p>
<p>The better solution is to use .NET&#39;s (experimental) AOT compilation feature (formerly called CoreRT). C# has had a number of attempts at an AOT compiler such as :</p>
2023-07-30 23:11:02 +00:00
<ul>
<li><a href="https://www.mono-project.com/docs/advanced/aot/">AOT</a> by Mono</li>
<li>LLD2CPP built by Unity</li>
<li><a href="https://docs.microsoft.com/en-us/dotnet/core/deploying/ready-to-run">Ready2Run</a> by Microsoft</li>
</ul>
2025-02-01 00:29:54 +00:00
<p>We&#39;ll be using the official Ready2Run AOT compilation built by Microsoft. In order to use it, all you have to do is add the following to your <code>nuget.config</code>:</p>
<pre><code class="lang-xml">&lt;<span class="hljs-keyword">add</span> key=<span class="hljs-string">"nuget.org"</span> <span class="hljs-keyword">value</span>=<span class="hljs-string">"https://api.nuget.org/v3/index.json"</span> protocolVersion=<span class="hljs-string">"3"</span> /&gt;
2023-07-30 23:11:02 +00:00
</code></pre>
2025-02-01 00:29:54 +00:00
<p>and then install the package: <code>Microsoft.DotNet.ILCompiler</code>. After doing that if you run the command: <code>dotnet publish -r [Runtime] -c [Config]</code> and after waiting a considerable amount of time, you&#39;ll have a full-fledged C# application compiled directly to your target runtime&#39;s bytecode!</p>
2023-07-30 23:11:02 +00:00
<p>Compiling my simple Hello, Wold test to linux-x64 (<code>dotnet publish -r linux-x64 -c Release</code>) and adding it to my project files should let me run it using the same method Arpan used in his blog.</p>
<p>After doing that, we can follow the instructions followed by Arpan and viola! C# runs on Gradescope!</p>
2025-02-01 00:29:54 +00:00
<p>I don&#39;t recommend this but it was fun to do and I needed stuff to write in a blog. </p>
2023-07-30 23:11:02 +00:00
<h2 id="other-interesting-low-level-c-net-features">Other Interesting (Low Level) C#/.NET Features</h2>
2025-02-01 00:29:54 +00:00
<p>C# actually has many lower level features people don&#39;t expect it to have. Some of these include pointers and direct memory management. Pointers can be enabled by encasing your code in an unsafe code block.</p>
2023-07-30 23:11:02 +00:00
<p>Example (Written by <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code">Microsoft</a>)</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Normal pointer to an object.</span>
<span class="hljs-keyword">int</span>[] a = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">5</span>] { <span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>, <span class="hljs-number">40</span>, <span class="hljs-number">50</span> };
<span class="hljs-comment">// Must be in unsafe code to use interior pointers.</span>
unsafe
{
<span class="hljs-comment">// Must pin object on heap so that it doesn't move while using interior pointers.</span>
2025-02-01 00:29:54 +00:00
fixed (<span class="hljs-keyword">int</span>* p = &amp;a[<span class="hljs-number">0</span>])
2023-07-30 23:11:02 +00:00
{
<span class="hljs-comment">// p is pinned as well as object, so create another pointer to show incrementing it.</span>
<span class="hljs-keyword">int</span>* p2 = p;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
<span class="hljs-comment">// Incrementing p2 bumps the pointer by four bytes due to its type ...</span>
p2 += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
p2 += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p2);
<span class="hljs-built_in">Console</span>.WriteLine(<span class="hljs-string">"--------"</span>);
<span class="hljs-built_in">Console</span>.WriteLine(*p);
<span class="hljs-comment">// Dereferencing p and incrementing changes the value of a[0] ...</span>
*p += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p);
*p += <span class="hljs-number">1</span>;
<span class="hljs-built_in">Console</span>.WriteLine(*p);
}
}
</code></pre>
<p>In .NET 6, the <code>NativeMemory</code> class was introduced which you can read about <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativememory.alloc?view=net-6.0">here</a>. It allows for malloc-like memory allocation and freeing which can be important for high-performance workloads.</p>
2023-08-20 18:47:57 +00:00
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
2023-07-30 23:11:02 +00:00
<footer>
<hr />
2025-02-01 00:29:54 +00:00
<p style="margin-bottom: 0px;">Copyright &#169; Nicholas Orlowsky 2025</p>
2023-11-16 18:14:34 +00:00
<p style="margin-top: 0px; margin-bottom: 0px;">Hosting provided by <a href="https://nws.nickorlow.com">NWS</a></p>
<p style="margin-top: 0px;">Powered by <a href="https://github.com/nickorlow/anthracite">Anthracite Web Server</a></p>
2023-07-30 23:11:02 +00:00
</footer>
</body>