使用 VS2005 產生 ATL COM 讓 WinCE 上的 ASP 可以呼叫到

有兩篇不錯的參考:

http://www.codeproject.com/Articles/38254/A-Beginner-Tutorial-for-Writing-Simple-COM-ATL-DLL
http://www.emtronix.com/article/article2009292.html

我依著第一個連結的方式,只要修正一個 VS 的 bug,就寫出可以在 ASP 呼叫到的 COM 了。這個 bug 會造成在 build 的時候出現如下錯誤:

error C2039: 'UpdateRegistry' : is not a member of 'CRemoteMon'

解決方式是找到以下 code:

#ifndef _CE_DCOM
DECLARE_REGISTRY_RESOURCEID(IDR_REMOTEMON)
#endif

然後將 #ifndef 的部份註解掉。

另外在函式的參數部份,我是參考第二個連結的建議,統一使用 VARIANT。然後再透過一個函式將 VARIANT 轉為 std::string,之後再轉為我要的 int 型態。轉換函式如下:

std::string ToString( const VARIANT & value )
{
if ( value.vt == VT_NULL )
return "";
else
return std::string( static_cast<const char*>( (_bstr_t)value ) );
}

上面函式需要再 include:

#include "comutil.h"
#include <string>

以及加入 comsuppw.lib 這個連結函式庫。

然後我的目的是要在 ASP 中呼叫這個 COM 的一個 method,再將它傳給在 WinCE device 中跑的一個 process。傳遞給 process 的方式這邊使用廣播式的 PostMessage。

STDMETHODIMP CSimpleCom::WriteAddrValue2(VARIANT vAddr, VARIANT vValue)
{
std::string strAddr = ToString(vAddr);
std::string strValue = ToString(vValue);

int nAddr = atoi(strAddr.c_str());
int nValue = atoi(strValue.c_str());

PostMessage(HWND_BROADCAST, WM_REMOTEMON_WRITE_ADDR, (WPARAM)nAddr, nValue);

return S_OK;
}

注意,因為我這邊只有傳 value,所以可以直接傳。如果要傳字串或者是 structure,則需要在 COM 這邊 new,然後在 message receiver 那邊做 delete 的動作。然而這樣子的方式是個不好的方式,會讓程式很難 debug。所以更好的方式是使用如 MsgQueue 這種 IPC 方式。

留言

熱門文章