Mitsubish의 MX Component를 x64에서 사용할 수 있는 것은 C#으로 가능하지 C++로는 불가능하다. 그렇기 때문에 COM으로 Service를 등록해서 인터페이스를 통한 작업을 할 수밖에 없다.
ATL을 이용하여 서버를 만들고 이를 이용하는 방법을 우선 숙지하자.
서버 만들기
이제 ATL의 기본 조작법을 익혔다면, 해당 프로젝트에 MX Component 기능들을 연결해야 한다. IMELServer라는 ATL Simple Object를 만든 후, 헤드 파일에 관련 헤드 파일을 include 하자.
// IMELServer.h : Declaration of the CIMELServer
#pragma once
#include "resource.h" // main symbols
#include "MELServer_i.h"
#include "ActUtlType_i.h" // For ActUtlType Control
#include "ActProgType_i.h" // For ActProgType Control
#include "ActDefine.h" // ACT Common Macro Header
그런 뒤, MX Component 를 사용하기 위한 ComPtr를 선언한다.
public:
CIMELServer();
CComPtr<IActUtlType> mp_IUtlType; // ACT Control (Custom Interface)
CComPtr<IActProgType> mp_IProgType; // ACT Control (Custom Interface)
소스 파일에는 소스파일을 Include해야 한다. 어떻게 된 건지 알 수 없지만 __uuidof()를 이용한 ID가 작동하지 않는다. 그렇기 때문에 소스 파일 안에 있는 Define을 사용한다.
#include "stdafx.h"
#include "IMELServer.h"
#include "ActUtlType_i.c" // For CustomInterface
#include "ActProgType_i.c" // For CustomInterface
// CIMELServer
CIMELServer::CIMELServer()
{
mp_IUtlType.CoCreateInstance(CLSID_ActUtlType, NULL, CLSCTX_INPROC_SERVER);
mp_IProgType.CoCreateInstance(CLSID_ActProgType, NULL, CLSCTX_INPROC_SERVER);
}
ComPtr의 인스턴스를 만들어서 사용가능하게 만든다. 그 뒤로는 MX Component 4.0의 메서드와 내가 만드는 메서드와 일대일 매칭을 해주면 된다. 물론 더 편리하게 만들 수도 있다. Open 같은 경우를 보자.
STDMETHODIMP CIMELServer::OpenProg(LONG* retVal)
{
HRESULT hr = mp_IProgType->Open(retVal);
return S_OK;
}
STDMETHODIMP CIMELServer::OpenUtl(LONG* retVal)
{
HRESULT hr = mp_IUtlType->Open(retVal);
return S_OK;
}
클라이언트 만들기
클라이언트 소스는 기본적으로 MX Component에서 제공하는 Sample 중에서 CostomSampleEng을 이용하면 된다. C:\MELSEC\Act\Samples\Vc 아래에 있다.
해당 부분에서 OnInitDialog() 에 있는 CoCreateInstance를 걷어내고, 앞에서 만든 Server를 이용해야 한다.. tlb 파일을 이용하여. tih 파일을 만든 후, 추가해 준다.
CComPtr<IIMELServer> melsec;
해당 ComPtr를 초기화 해야 하는데, 이상하게 OnInitDialog()에서 호출하면 문제가 발생한다. 이유는 아직 잘 모르겠다. 그래서 Dialog가 다 만들어진 후, Open Button에 해당 초기화를 함께 추가하였다.
void CMELClientDlg::OnOpenCom()
{
melsec.CoCreateInstance(__uuidof(IMELServer), NULL, CLSCTX_LOCAL_SERVER);
long lRet;
CWnd::UpdateData(TRUE);
// Clear ReturnValue Display
m_RetVal = "";
m_RetVal2 = "";
m_RetVal3 = "";
if (m_SelectCntl == 0) // ActProgType Control (Custom Interface)
{ // If you don't use default values, please set their properties before OPEN method call.
// (If you call the set-property method after OPEN method, it isn't reflected to the communication.)
// (You can use methods to set and get the value for all properties.)
// ---> Example: Change Unit type to "QNUSB" from default value.
// Change Protocol type to "USB" from default value.
// The other is default.
melsec->SetActUnitType(UNIT_QNUSB);// Exec set-property method
melsec->SetActProtocolType(PROTOCOL_USB);
lRet = melsec->OpenProg();
m_RetVal.Format(L"0x%08x", lRet);
}
else // ActUtlType Control (Custom Interface)
// If you don't use default values, please set their properties before OPEN method call.
//---> Example: Change the Logical station number to "2" from default value.
{
melsec->SetActLogicalStationNumber(2);
lRet = melsec->OpenUtl();
m_RetVal.Format(L"0x%08x", lRet);
}
UpdateData(FALSE);
}
해당 작업을 실행하면 x64에서도 제대로 동작함을 확인할 수 있다.
'산업기술 > MELSEC' 카테고리의 다른 글
[MELSEC] MX Component 4.0 x64에서 ALTCOMCLI.h 에러 처리 (0) | 2022.04.21 |
---|