C# 에서 DLL 함수 호출

개요

프로젝트를 진행하다 보면 외부 시스템이나 장비와 연동해야 하는 경우가 있습니다. DLL 파일과 부실한 문서만 전달해 주고 ‘알아서 해라!’ 라는 식으로 진행되는 경우가 많습니다. 이런 경우 C# 에서 DLL 함수 호출 을 해야 합니다. 이런 DLL 들은 대부분 .NET 기반에서 만들어진 것이 아닙니다. .NET 기반에서 만들어진 경우는 참조해서 사용하면 됩니다. .NET 기반이 아닌 DLL을 참조하려고 하면 다음과 같은 오류가 발생합니다.

.NET 기반이 아닌 DLL 을 참조하면 발생하는 오류

.NET 기반이 아닌 DLL 을 참조하면 발생하는 오류

준비

WebForm, WinForm 모두 방식은 동일합니다. WebForm 기준으로 살펴보도록 하겠습니다. 사용할 DLL은 GetIPAddress 메소드만 존재합니다. 호출하면 IP 주소와 PC 이름을 변수에 담아 전달해 주는 기능을 합니다.

먼저 코드 상단에 다음과 같이 DLL Import 부분과 함수정의 부분을 작성합니다.

[DllImport("yourdll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
extern static void GetIPAddress([Out, MarshalAs(UnmanagedType.LPArray)] byte[] ipAddress, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pcName);
extern static void GetIPAddress(byte[] ipAddress, byte[] pcName);

CallingConvention = CallingConvention.StdCall 이 부분이 없으면 다음과 같은 오류가 발생합니다.

추가 정보: PInvoke 함수 ‘DLLCallTest!DLLCallTest.index::GetIPAddress’에 대한 호출 결과 스택이 불안정하게 되었습니다. 관리되는 PInvoke 시그니처와 관리되지 않는 대상 시그니처가 일치하지 않기 때문인 것 같습니다. 호출 규칙 및 PInvoke 시그니처의 매개 변수와 관리되지 않는 대상 시그니처가 일치하는지 확인하십시오.

그러므로 호출표기법에 대한 사항을 명시적으로 지정해 주어야 합니다.

2행의 정의는 좀더 상세하고 3행의 정의는 일반적으로 사용하는 형태입니다.

호출

함수 호출은 동일하게 하면 됩니다. 그런데 인수의 자료형이 byte 배열로 되어 있습니다. 인수의 자료형을 string으로 하면 될 것 같은데 왜 그럴까요? 실제로 string 으로 하고 실행해보면 결과가 정상적으로 반환되지 않습니다.

extern static void GetIPAddress(string ipAddress, string pcName);

string ipAddress = String.Empty;
string pcName = String.Empty;

GetIPAddress(ipAddress, pcName); //결과가 반환되지 않음	

변수에 값을 전달해 주는 것이니 ref 를 붙여 정의하고 호출해 보면 AccessViolationException이 발생합니다.

extern static void GetIPAddress(ref string ipAddress, ref string pcName);

string ipAddress = String.Empty;
string pcName = String.Empty;

GetIPAddress(ref ipAddress, ref pcName); //오류발생
ref 형식으로 호출하면 오류발생

ref 형식으로 호출하면 오류발생

string 형으로 정의되면 DLL 쪽 함수에서 string 변수의 값을 변경할 수 없어 오류가 발생하게 됩니다. 정상적으로 값을 가져오려면 다음과 같이 byte 배열 형태로 정의해야 합니다. byte 배열로 값을 받고 그것을 string 형태로 변환해서 사용하면 됩니다. GetIPAddress 함수는 전달된 인수에 결과값을 할당합니다. 인수가 아닌 return 값으로 반환이 되는 경우 string으로 정의하여 사용하면 됩니다.

extern static void GetIPAddress(byte[] ipAddress, byte[] pcName);

byte[] ipAddress = new byte[250];
byte[] pcName = new byte[250];

GetIPAddress(ipAddress, pcName);

Response.Write("ip : " + System.Text.Encoding.Default.GetString(ipAddress));
Response.Write("pcName : " + System.Text.Encoding.Default.GetString(pcName));
정상적으로 할당된 값

정상적으로 할당된 값

이제까지 C# 에서 DLL 함수 호출 하는 방법을 알아보았습니다.

개발자에게 유용한 사이트 소개

개요

개발을 진행하다보면 사소한 것에 많은 시간을 쓰는 경우가 있습니다. 이럴때 작업을 쉽게 해주는 도구나 사이트를 적절하게 이용하면 시간을 절약할 수 있습니다. 개발자에게 유용한 사이트 를 알아보도록 하겠습니다.

JSON Formatter

XML 보다는 자료 전달을 위해 JSON을 더 많이 사용하게 됩니다. 가끔 텍스트로 구성된 내용을 확인해야 하는 경우가 있습니다. 텍스트 에디터에서 보면 쉽게 원하는 부분을 찾기가 어렵습니다. 그럴때 유용하게 사용할 수 있는 사이트 입니다. JSON 내용을 붙여넣고 Process 버튼을 클릭하면 검증도 해 주고 각 요소별로 들여쓰기가 되어 보기 편한 상태로 나타납니다.

https://jsonformatter.curiousconcept.com/

JSON Formatter

JSON Formatter

원하는 크기의 이미지 표시 placehold.it, placeimg.com

웹 개발을 하다보면 화면에 특정한 크기의 이미지들이 반복적으로 나타나야 하는 경우가 있습니다. 그 외에도 다양한 크기의 이미지들이 사용됩니다. 이럴 때 이미지 파일을 별도로 만들지 않고 placehold.it 사이트를 이용하면 편리하게 나타나게 할 수 있습니다. img 태그 소스에 다음과 같이 원하는 크기를 지정하면 됩니다.

<img src=”http://placehold.it/187×60″ />

placehold 이미지 실제 모양

placehold 이미지 실제 모양

텍스트가 나타나는 것보다 실제 이미지가 나타나기를 원하면 placeimg.com 를 이용하면 됩니다. img 태그 소스에 다음과 같이 지정하면 됩니다.

<img src=”https://placeimg.com/640/480/any” />

640*480 이미지를 무작위로 보여주게 됩니다. 필요한 크기로 숫자를 변경해서 이용하면 됩니다.

내용 채우기 Lorem Ipsum

사이트 레이아웃을 협의할 때 화면 영역에 내용을 채워야 하는 경우가 있습니다. 내용을 받았을 경우 문제가 없지만 초기에는 필요한 자료를 받지 못한 경우가 많습니다. 이럴때 내용을 무엇으로 채워야 할지 애매한 경우가 많습니다. 뉴스 텍스트를 채워보기도 하고 의미없는 글자를 입력해 보기도 합니다. 이럴때는 www.lipsum.com 사이트를 이용하면 편리합니다.

Lorem Ipsum 사이트

Lorem Ipsum 사이트

문단, 단어, 전체 bytes 수를 입력하고 생성 버튼을 클릭하면 내용이 생성되어 나타납니다. 이것을 복사 후 붙여넣기 하여 사용하면 됩니다.

한글로 생성해 주는 사이트도 있습니다. 다음의 주소에서 확인할 수 있습니다.

hangul.thefron.me

한글 Lorem Ipsum

한글 Lorem Ipsum

개발자의 시간을 줄여주는 유용한 사이트를 알아보았습니다.