C# Interop with C/C++ 주제로 Native DLL을 C#에서 호출하여 사용하는 예1를 살펴보았는데 이번 주제는 Delphi DLL 파일을 C#에서 사용하는 예제를 작성해보았다. 모두 64bit로 빌드하였고 사용한 .NET 버전은 5.0이다. 예제에 사용한 소스 중 일부는 programmerall.com2에서 참고하였다.
library TestLib;
uses
System.SysUtils, System.Classes, System.AnsiStrings;
{$R *.res}
function GetResultP(inputString: PAnsiChar): PAnsiChar; stdcall; export;
var
pstr: PAnsiChar;
begin
pstr := PAnsiChar(AnsiString(' : 가나닭'));
Result := System.AnsiStrings.StrCat(inputString, pstr);
end;
function GetResult(inputStirng: PChar): PChar; stdcall; export;
var
str: PChar;
begin
str := PChar(' : 마바삵');
Result := StrCat(inputStirng, str);
end;
exports GetResultP, GetResult;
begin
end.
클래스의 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴(Singleton pattern)이라고 한다1. 정적 클래스(Static Class)와 비교해 싱글턴은 인터페이스 구현, 비동기 지원2 등 OOP에 더 어울리는 장점3을 가지고 있다.
Winform 응용프로그램에서 단일 인스턴스를 유지하고 이에 따라 하위 Winform이 프로그램 종료 시점까지 그 상태를 유지하기 원한다면 Winform을 싱글턴 패턴으로 만들어 사용하면 된다. 즉 하위 폼을 호출할 때 새로운 인스턴스(new)가 생성되는 것을 방지하고 처음에 생성한 폼을 지속해서 유지할 때 유용하다. 더욱 자세한 소스는 여기(github)에서 볼 수 있다.
using System;
using System.Windows.Forms;
namespace WinFormsApp
{
internal static class Program
{
[STAThread]
private static void Main()
{
// https://docs.microsoft.com/dotnet/api/system.windows.forms.highdpimode
// DpiUnaware, DpiUnawareGdiScaled, PerMonitor, PerMonitorV2, SystemAware
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
Application.EnableVisualStyles(); // Theme Enable
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(FormMain.Go); // Singleton Form
}
}
}
C#에서 SerialPort를 사용 시 문자 인코딩 문제가 발생할 때 Microsoft에서 지정한 인코딩 목록을 참고하여 이 문제를 해결하는데 Singleton 패턴1을 적용한 SerialPort Manager class2와 닷넷의 Encoding Class를 사용하였다. 아래의 표는 대표적인 한글 관련 인코딩 목록3이다.
코드페이지 | 이름 | 표시이름 |
---|---|---|
949 | ks_c_5601-1987 | 한국어 |
51949 | euc-kr | 한국어(EUC) |
65001 | utf-8 | 유니코드(UTF-8) |
Windows 프로그램은 기본적으로 UTF-8 중심으로 문자열을 처리한다. 그러나 MS-Windows는 euc-kr을 확장한 CP949(MS949)와 Unicode로 한글을 처리하므로 MS-Windows에서는 영문, 숫자와 별개로 한글을 byte 단위로 처리할 때 2byte 또는 3byte의 문자가 혼재할 수 있다4. 아래의 예제는 2byte (AnsiString) 한글을 처리할 필요가 있을 때 참고할 만한 소스이다.
Encoding 클래스에서 기본적으로 제공하는 ‘ASCII, Default, UTF8’ 외에 Encoding.CodePages 에서 제공하는 GetEncoding 함수5를 사용하여 코드 페이지를 지정할 수 있다. SerialPort Manager class는 원저자의 소스를 수정하여 사용하였다.