[C#] C# DLL이 아닌 DLL파일 연결하여 사용하기

가우스메터 라는 장비와 연동하는 프로그램을 만들어야 한다

오랫만에 회사에서 연락왔다. 앞뒤사정 다 생략하고 결론부터 말하면 역시 뭔가 해달라는거였다. 가우스메터? 라는 장비랑 연동하여 주기적으로 값을 읽어 그 수치가 일정 이상일 경우 생 X랄발광을 하는 프로그램을 만들어야 한다. 물론 데이터 저장은 기본이고... 지X발광 하는거야 어렵지 않다고 생각했고, 데이터 저장도 별로 어렵지 않다고 생각했다. 늘 하는 방식이 있으니까. 근데 문제는 이 장비와의 통신은 USB여야 한다는 것.

사실 나는 프로그래머라기 보다는 그냥 인터넷에 있는 코드를 복붙해와 적당히 수정하고 적당히 작동되게 하는 그냥 그런 사람인데, USB 통신을 좀 도와달라는 부탁에 차마 거절은 못하고 일단 가서 확인해보겠다고 했다.


DLL 파일이 있긴 한데, C#에서 열리지 않는다.

해당 장비의 제조사에서 프로그램 개발하라고 DLL 파일을 제공했다. 일단 이걸 사용법을 알아야 하는데, 내가 알고 있는 사용법은 참조에 DLL파일을 넣는 것 정도... 당연히 그 방법을 먼저 시도했다. 안된다.

명세서를 보니 이 DLL파일은 C++로 만들어진거라 C나 C++(MFC), VB에서 제대로 작동하는듯, 예제 프로그램도 엑셀에 포함된 VB 메크로로 작동한다.

물론 DLL파일만 덩그러니 있고 나머지는 설명서 뿐이다. 뭐 드라이버류도 있고 한데 일단 개발에 필요한건 DLL파일이고 이를 사용할 방법인데..


DllImport("file")

기존 C++ 프로젝트들과 호환성을 고려하기 위한것인지, C#에는 이런게 있다. 바로 외부 DLL 파일을 코드에서 동적으로 활당하게 하는것. 물론 이것만 쓰면 안되고, 이 DLL 안에 있는 함수도 같이 정의해서 C# 프로젝트에서도 쓸 수 있게 해야 한다. 그러면 그 함수는 어디서 얻냐. 라고 하면, DLL 파일을 개발하라고 제공하면 그 DLL에서 쓸 수 있는 함수와 설명이 있는 문서도 같이 제공하니 그걸 참고하면 된다.


  1. 즉, 먼저 DLL파일과 설명서를 준비하고 설명서를 먼저 본다. 예시는 가우스메터 장비와 통신하기 위해 필요한 gm0.dll이라는 DLL 파일과 그의 설명서이다. 아래와 같이 문서 안에 어떤 함수가 있고 어떤 기능을 하는지가 정확히 적혀 있다. 개발환경에 맞는 자료형으로 만들어져 있을테니 당연히 C#에 맞는 자료형으로 적당히 수정한다.


  2. DLL파일은 프로그램의 exe 파일과 같은 경로안에 준비한다. 프로젝트 안에 넣으면 어떻게 될지 모르겠는데 내 생각에는 안될 것 같다. 그리고 위의 설명서에서 사용하고자 하는 함수를 보고 그에 맞춰 적는다. 예시에서는 장비와의 새로운 커낵션을 만드는 gm0newgm, 장비와 연결하는 gm0startconnect, 장비에서 값을 읽어오는 gm0getvalue 라는 함수 3개를 사용할 것이다. DllImport를 사용하려면 System.Runtime.InteropServices; 를 using 해야 하고, 클래스 선언후 밑에, 메소드 밖에 써주면 된다. 함수의 접근지정자도 맘대로 해도 된다. 단 static extern으로 선언해야 한다.(생각해보면 당연하다)


    using System.Runtime.InteropServices;
    
    [DllImport("gm0.dll")]
    private static extern int gm0_newgm(int port, int mode);
    
    [DllImport("gm0.dll")]
    private static extern int gm0_startconnect(int hand);
    
    [DllImport("gm0.dll")]
    private static extern double gm0_getvalue(int hand);
    
  3. 이제 원하는곳에서 해당 함수를 쓰고 동작을 확인하자. 아래 예제에서는 ERROR:-2 라고 표시됬는데 이는 장비와 연결할 수 없을때 나오는 에러 코드 중 하나이니 결과적으로 DLL파일의 연결은 잘 되었다고 할 수 있다. 만약 DLL파일이 없다면, GDI+ 예외가 뜨거나 아까 using으로 사용한 System.Runtime.InteropServices 예외가 뜨니, 이를 적절히 처리하면 될 것이다.



Minny_

,