MCS UDP Program
- DLL Protocol 구현
- 기존 API를 활용하기 위한 marshalling 작업
- Network 관련 오류 처리 및 Timeout 기능 적용
세부 일정
- 12.30
VirtualTableProtocol.dll
생성
- 클래스 라이브러리 생성
- 새 클래스 빌드
Build Dependencies
, References
체크
- 01.07
IMcs
인터페이스 생성
- 기존
VirtualTableProtocol
이 상속
- 새로운 protocol과의 연결 >> 확장성
MCS Protocol
마샬링(marshalling)
EMotionMcsDevice
프로그램의 C++ 코드와 C# 코드 사이의 통신
- 데이터 타입 맞추기
- 01.10
MCS Protocol
마샬링 성공
- 콤보박스 초기값 설정 완료
- IMcs 인터페이스 적용된 MCS UDP Program 다이어그램 완성
- 01.14
MCS threadNet
네트워크 에러 처리 코드 추가
virtualProtocolTable
의 Set_I_Var
및 Set_LR_Var
ref 매개변수 설정
threadingData
에서 값 설정
Form1
의 timer
에서 flag
값에 따라 서로 다른 Type(int/string)의 결과 받음
data=0
에 대해 에러 처리를 하지 않도록 string 변수 따로 마련
- 추후
MCSdll
에 적용 예정
- 01.17
- 매개변수 타입을
object
로 통일
- int, string 변수를 나눌 필요가 없게 됨에 따라 flag 변수도 제거
- threadNet 브랜치에 Combobox 초기값 설정 적용
- Timeout Messagebox("Timeout Error") 추가
- connect button의 Messagebox("접속 완료") 제거
- 01.21
threadNet
브랜치의 변경 내용을 McsDLL
브랜치에 유사하게 적용
object
type 코드에서 flag
에 따라 string
과 int
type을 받는 코드로 복귀
ThreadingData
와 VirtualTableProtocol
로 나누어서 dll 생성
DllProtocol
클래스에 에러 처리 코드 작성
- 원활한 WPF 작성을 위해 다시
object
type으로 변경
- 동작 모두 확인(에러 처리 코드, vtp/dp, ...)
참고
- 마샬링(marshalling)
- 관리 코드와 네이티브 코드 간에 변환해야 하는 경우 형식을 반환하는 프로세스
- 관리 코드와 비관리 코드의 형식이 서로 다르기 때문에 필요하다
// C/C++ 기본 호출 규칙, 스택(오른쪽>>왼쪽)
[DllImport("EMotionMcsDevice.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int eMcsSetQPoint(int address, int data);
- 마샬링 절차
- C++ DLL 파일 생성
- 마셜링 할 C# 파일 경로에 생성한 DLL 파일 복사/붙여넣기
[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
- MyDll.dll 안에서 함수를 import 할 것이다
extern public static int sum(int a, int b);
- MyDll.dll 안에 있는 함수 중 sum을 가져올 것이다
- C#에 존재하지 않는 타입이 포함된 함수를 import할 경우, marshalling 필요
- C++의
char*
를 C#에서 char[]
로 받기
class Marshalling
{
[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
extern public static int sum(int a, int b);
[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
extern public static void MyMessage(char[] ch);
static void Main(string[] args)
{
int _sum = sum(1, 3);
Console.WriteLine("sum: {0}", _sum);
// C++에 없는 String 타입을 넘기려면 char 배열로 바꿔서 넘겨야 한다
String _MyMessage = "Dll Marshalling Sucess !\n";
char[] _MyMessage_CharArray = _MyMessage.ToCharArray();
MyMessage(_MyMessage_CharArray);
Console.WriteLine("");
Console.WriteLine("Press Enter Key...");
Console.ReadLine();
}
}
- 참조 매개변수(
ref
), 출력 매개변수(out
)
- call by reference
- C언어의 포인터와 대응되는 개념
- out의 경우, 함수 내 값을 반드시 초기화해야 한다
private static void Sum(int a, int b, out int sum)
{
sum = a + b;
return;
}
static void Main()
{
int total = 10;
Console.WriteLine(total);
sum(20,40,out total);
Console.WriteLine(total);
10
60