ATL入门
服务端代码------------------------------------------------------------------------------------------------------------------------------------------------------------
altstopwatch.idl [接口定义文件]
// altstopwatch.idl : IDL source for altstopwatch // // This file will be processed by the MIDL tool to // produce the type library (altstopwatch.tlb) and marshalling code. import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(FD2BE6F3-9074-47F3-9884-FDD3DE13D158), pointer_default(unique) ]
</pre><pre code_snippet_id="458982" snippet_file_name="blog_20140827_3_5235692" name="code" class="plain">//在这里定义接口 interface Istopwatch : IUnknown{
<span style="white-space:pre"> </span> //同样的属性(都指向同一个成员变量),ID值同样 <strong><span style="font-size:18px;color:#ff0000;"> [propget, id(1), helpstring("取值")] HRESULT name ([out ,retval] BSTR *val); [propput, id(1), helpstring("设值")] HRESULT name([in] BSTR val);</span></strong> }; [ uuid(A4E51DE3-D343-4CB2-A901-5CE1D2067309), version(1.0), ] library altstopwatchLib { importlib("stdole2.tlb"); [ uuid(FD3216FD-B513-40F1-BE2C-72B2954D1368), helpstring("help string stopwatch class") ] coclass stopwatch { [default] interface Istopwatch; }; };
// stopwatch.h : Declaration of the Cstopwatch #pragma once #include "resource.h" // main symbols #include "altstopwatch_i.h" #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms." #endif using namespace ATL; // Cstopwatch class ATL_NO_VTABLE Cstopwatch : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<Cstopwatch, &CLSID_stopwatch>, public Istopwatch { public: Cstopwatch() { } DECLARE_REGISTRY_RESOURCEID(IDR_STOPWATCH) BEGIN_COM_MAP(Cstopwatch) COM_INTERFACE_ENTRY(Istopwatch) END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } public:
//将接口进行实现 <strong><span style="font-size:18px;color:#ff6600;">public: virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_name( /* [retval][out] */ BSTR *val) { m_name.CopyTo(val); return S_OK; } virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_name( /* [in] */ BSTR val) { m_name.AssignBSTR(val); return S_OK; }</span></strong> private: CComBSTR m_name; }; OBJECT_ENTRY_AUTO(__uuidof(stopwatch), Cstopwatch)
###############################################################################################################################
client代码
#include <Windows.h> #include <atlbase.h> #include <atlcom.h> #include <stdio.h> #import "../Debug/altstopwatch.dll" named_guids no_namespace void test() { CoInitialize(NULL); { CComPtr<Istopwatch> ptr ; HRESULT hr = ptr.CoCreateInstance(CLSID_stopwatch, NULL, CLSCTX_ALL); assert((SUCCEEDED(hr))); //因为我之前写成了 //BSTR s = L"test" //所以::SysAllocStringByteLen算出来一直是0 汗啊!!!!!!!!!!!!!! BSTR s = ::SysAllocString(L"test"); //对这个进行求值的字符串。必须由::SysAllocByte分配 int len = ::SysStringByteLen(s); int len2 = ::SysStringByteLen(L"ffffff"); assert(len==8); assert(len2 == 0); BSTR m_str = ::SysAllocStringByteLen((char*)s, len); ptr->put_name(s); BSTR sr = NULL; ptr->get_name(&sr); int r = wcscmp(s, sr); assert(r == 0); ::SysFreeString(s); printf("access resource success!"); } CoUninitialize(); } int main(int argc, char *argv[]) { test(); getchar(); return 0; }