服务端代码------------------------------------------------------------------------------------------------------------------------------------------------------------
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)
###############################################################################################################################
客户端代码
#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;
}