아마존 사이언스 블로그 소식에 의하면 기존 Javascript 코드 레이어로 구성한 Prime Video 서비스를 Rust, WebAssembly로 전환하여 안정성과 속도를 향상했다고 한다.1
또한, theregister.com의 기사에 의하면 마이크로소프트는 Windows커널을 Rust로 작성하고 있다고 한다. Microsoft is rewriting core Windows libraries in the Rust programming language, and the more memory-safe code is already reaching developers.2
이처럼 Rust는 차세대 시스템 프로그래밍 언어로 위치를 굳건히 다져가고 있다. 위의 이미지는 Rust를 학습하는 데 필요한 추천 서적을 소개한 것이다.
C#은 동시성(Concurrency) 구현을 쉽게 할 수 있는데 이번 글에서 여러 개의 비동기 함수를 병렬처리 형태로 구현해 보는 예제를 살펴볼 것이다. Concurrency 방식과 Parallel 방식의 비교1는 이전 글인 Concurrency in C# Example 에서 살펴보았다.
아래의 예제처럼 각 1초, 2초, 3초를 소요하는 비동기 방식의 함수가 3개 있다고 가정하고 IProgress 또는 리턴값을 처리한다고 하면 총 6초가량이 걸리게 된다.
async Task Main()
{
string returnValue1 = await ProgressA(); //1초
string returnValue2 = await ProgressB(); //2초
string returnValue3 = await ProgressC(); //3초 : 총 6초
}
위의 예제를 아래처럼 Concurrency를 사용하면 총 3초가 소요되는 병렬처리가 가능하다2.
닷넷은 Win32 API와 같은 Native DLL을 using System.Runtime.InteropServices
네임스페이스를 통해 호출하는 방법을 제공한다. C++1, Delphi2에서 작성한 DLL 파일을 호출하는 방법은 이미 살펴보았다.
이번 글에서 살펴볼 것은 .NET 7에서 제공하는 Native AOT 컴파일을 사용하여 C#으로 Native DLL을 만들고 이를 불러와 사용하는 간단한 예제이다3. 아래의 소스처럼 ‘NativeLibrary’ 이름으로 프로젝트(DLL, .NET7)를 만든다. 특히 UnmanagedCallersOnly
는 바로 해당 함수를 export 하는 용도로 사용할 수 있게 해준다.
using System.Runtime.InteropServices;
namespace NativeLibrary;
public class Class1
{
[UnmanagedCallersOnly(EntryPoint = "add")]
public static int Add(int a, int b)
{
return a + b;
}
[UnmanagedCallersOnly(EntryPoint = "sumstring")]
public static nint SumString(nint first, nint second)
{
string? my1String = Marshal.PtrToStringAuto(first);
string? my2String = Marshal.PtrToStringAuto(second);
string sum = my1String + my2String;
nint sumPointer = Marshal.StringToHGlobalAuto(sum);
return sumPointer;
}
}
nint
타입은 Native int를 말하는데 플랫폼(32/64bit)에 따라 다른 크기를 갖는 정수이다. 위의 소스를 아래의 프로젝트 컴파일 옵션을 사용하여 dll 파일을 생성한다. 자세한 내용은 Building Native Libraries with NativeAOT를 참고한다.