请问,怎样才能用c实现com?在很多书上都是用c++。 能不能给个简单的例子,或有关文档。谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 应该说, C 是不可能实现com 的,C 不是OOL , 要知道,vtable 是 com 的基石。 no,只要你搞到com binary的格式,那么恭喜你你可以用c完全实现那样的binary格式,vtable 嘛,拿指针狂写就是了。其实就是重新实现一把COM,太 太难了。 哦很无聊,试下:#include <objbase.h>// {1BED467F-0934-4c7c-B657-472FEB0ED7F9}static const GUID IID_ITestComWithC = { 0x1bed467f, 0x934, 0x4c7c, { 0xb6, 0x57, 0x47, 0x2f, 0xeb, 0xe, 0xd7, 0xf9 } };// {AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}static const GUID CLSID_TestComWithC = { 0xaa38e64d, 0x7812, 0x4ed1, { 0xb0, 0xcc, 0x1b, 0xa4, 0xb1, 0x17, 0xe1, 0x2c } };BOOL APIENTRY DllMain( HANDLE h, DWORD w, LPVOID p ){ return TRUE;}typedef struct ITestComWithC_Vtbl{ BEGIN_INTERFACE /* IUnknown */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(); ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(); ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(); STDMETHOD( set_TestProp )(); STDMETHOD( get_TestProp )(); STDMETHOD( TestMethod1 )(); END_INTERFACE} ITestComWithC_Vtbl;typedef struct ITestComWithC_Impl_Simple{ CONST_VTBL struct ITestComWithC_Vtbl* lpVtbl; ULONG m_refcount; long m_prop;} ITestComWithC_Impl_Simple;STDMETHODIMP ITestComWithC_Impl_Simple_QI( IUnknown* This , REFIID riid , void** ppv ){ if( !memcmp( &IID_IUnknown , riid , sizeof( GUID ) ) || !memcmp( &IID_ITestComWithC , riid , sizeof( GUID ) ) ) { This->lpVtbl->AddRef( This ); *ppv = (void*)This; return S_OK; } *ppv = NULL; return E_NOINTERFACE;}STDMETHODIMP_(ULONG) ITestComWithC_Impl_Simple_Addref( ITestComWithC_Impl_Simple* This ){ InterlockedIncrement( &This->m_refcount ); return This->m_refcount;}STDMETHODIMP_(ULONG) ITestComWithC_Impl_Simple_Release( ITestComWithC_Impl_Simple* This ){ if( 0 == InterlockedDecrement( &This->m_refcount ) ) { CoTaskMemFree( This ); return 0; } return This->m_refcount;}STDMETHODIMP ITestComWithC_Impl_Simple_set_Prop( ITestComWithC_Impl_Simple* This , long a ){ This->m_prop = a; return S_OK;}STDMETHODIMP ITestComWithC_Impl_Simple_get_Prop( ITestComWithC_Impl_Simple* This , long* a ){ if( !a ) return E_INVALIDARG; *a = This->m_prop; return S_OK;}STDMETHODIMP ITestComWithC_Impl_Simple_TestMethod1( ITestComWithC_Impl_Simple* This , long a , long b , long* c ){ if( !c ) return E_INVALIDARG; *c = a + b + This->m_prop; return S_OK;}static CONST_VTBL ITestComWithC_Vtbl vtbl_TestComWithC = { ITestComWithC_Impl_Simple_QI, ITestComWithC_Impl_Simple_Addref, ITestComWithC_Impl_Simple_Release, ITestComWithC_Impl_Simple_set_Prop, ITestComWithC_Impl_Simple_get_Prop, ITestComWithC_Impl_Simple_TestMethod1};HRESULT STDMETHODCALLTYPE SFI_QueryInterface( IClassFactory __RPC_FAR * This, /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject){ if( !memcmp( &IID_IClassFactory , riid , sizeof( GUID ) ) || !memcmp( &IID_IUnknown , riid , sizeof( GUID ) ) ) { *ppvObject = This; return S_OK; } return E_FAIL;} ULONG STDMETHODCALLTYPE __RPC_FAR SFI_AddRef( IClassFactory __RPC_FAR * This){ return 1;} ULONG STDMETHODCALLTYPE __RPC_FAR SFI_Release ( IClassFactory __RPC_FAR * This){ return 1;} /* [local] */ HRESULT STDMETHODCALLTYPE __RPC_FAR SFI_CreateInstance( IClassFactory __RPC_FAR * This, /* [unique][in] */ IUnknown __RPC_FAR *pUnkOuter, /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject){ if( pUnkOuter ) return E_FAIL; if( !memcmp( riid , &IID_IUnknown , sizeof( GUID ) ) || !memcmp( riid , &IID_ITestComWithC , sizeof( GUID ) ) ) { ITestComWithC_Impl_Simple *pThis = CoTaskMemAlloc( sizeof( ITestComWithC_Impl_Simple ) ); if( !pThis ) return E_OUTOFMEMORY; pThis->lpVtbl = &vtbl_TestComWithC; pThis->m_prop = 0; pThis->m_refcount = 1; *ppvObject = pThis; return S_OK; } return E_FAIL;} /* [local] */ HRESULT STDMETHODCALLTYPE __RPC_FAR SFI_LockServer( IClassFactory __RPC_FAR * This, /* [in] */ BOOL fLock) { return S_OK; }static IClassFactoryVtbl vtbl_IFC = { SFI_QueryInterface, SFI_AddRef, SFI_Release, SFI_CreateInstance, SFI_LockServer};STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv){ static IClassFactory icf = { &vtbl_IFC }; if( !memcmp( rclsid , &CLSID_TestComWithC , sizeof( GUID ) ) && !memcmp( riid , &IID_IClassFactory , sizeof( GUID ) ) ) { *ppv = &icf; return S_OK; } return CLASS_E_CLASSNOTAVAILABLE;}STDAPI DllCanUnloadNow(void){ return S_FALSE;} idl 文件 :import "oaidl.idl";import "ocidl.idl";[ uuid(03F1CF27-F63E-418f-8C64-F64FA20362DC), version(1.0)]library libTestComWithC{ importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ object, uuid(1BED467F-0934-4c7c-B657-472FEB0ED7F9), pointer_default(unique) ] interface ITestComWithC : IUnknown { HRESULT set_TestProp( long a ); HRESULT get_TestProp( [out,retval]long* valRet ); HRESULT TestMethod1 ( long a , long b , [out,retval]long* valRet ); }; [uuid(AA38E64D-7812-4ed1-B0CC-1BA4B117E12C)] coclass TestComWithC { interface ITestComWithC; };};-----------------------------------------------------------------------不想写 RegSvr && UnRegSvr 两个函数, 用 reg 文件:Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\CLSID\{AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}]@="TestCOMWithC Object"[HKEY_CLASSES_ROOT\CLSID\{AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}\InprocServer32]@="D:\\MyWork\\Demo\\TestCOMWithC\\Debug\\TestCOMWithC.dll""ThreadingModel"="Both"[HKEY_CLASSES_ROOT\CLSID\{AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}\TypeLib]@="{03F1CF27-F63E-418f-8C64-F64FA20362DC}"-----------------------------------------------------------------.rc 里加上 1 TYPELIB "TestCOMWithC.tlb" 你可以参考 ATL 的源码 ATL是C++地哟.用C写COM还是满简单地哟 不懂。帮你顶。问个问题。blog的密码和登录CSDN的密码一样吗?我怎么登录不了Blog. 晕 系统在编译idl文件时就会同时生成C和CPP两个版本的接口定义嘛 代理兄不过Copy了一下 可以用C写COM的。这样定义接口:typedef struct tag_IUnknownVtbl{ HRESULT (__stdcall * pQueryInterface) (ComObject * this, REFIID iid, void ** ppvObject); LONG (__stdcall * pAddRef) (ComObject * this); LONG (__stdcall * pRelease) (ComObject * this);} IUnknownVtbl;COM对象typedef struct tag_ComObject{ IUnknownVtbl * pVtbl; /* 后面是自己定义的东西 */} ComObject;取得COM对象:IUnknown * GetObject(){ ComObject * pObj = (ComObject *)malloc(sizeof(ComOBject)); pObj->pVtbl = (IUnknownVtbl *)malloc(sizeof(IUnknownVtbl)); pObj->pVtbl.pQueryInterface = xxx; pObj->pVtbl.pAddRef = xxx; pObj->pVtbl.pRelease = xxx; return (IUnknown *)pObj;}以上代码没有测试,仅供参考。 有本 c实现 com的书,英文版, 自己找找吧. 怎样检测串口已经打开,或被其它设备打开了? 这段小代码这么理解? 有没有做过像CPU占用那样的动态曲线变化图 如何获得你所生成的应用程序的路径? 高分求助,如何获取datagrid选中的某一行的数据??? 小弟我现在刚看《深入栈出MFC》 80分求教,如何获得系统的当前时刻,或两次操作的时间间隔,要精确到微妙 如何选中一个画好的圆? CDC类的TextOut函数在Windows2000 Advanced里怎么与98里不一样 大家一起来讨论用VC为WindowsCE编程 关于标签多文档 多播问题
static const GUID IID_ITestComWithC =
{ 0x1bed467f, 0x934, 0x4c7c, { 0xb6, 0x57, 0x47, 0x2f, 0xeb, 0xe, 0xd7, 0xf9 } };// {AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}
static const GUID CLSID_TestComWithC =
{ 0xaa38e64d, 0x7812, 0x4ed1, { 0xb0, 0xcc, 0x1b, 0xa4, 0xb1, 0x17, 0xe1, 0x2c } };
BOOL APIENTRY DllMain( HANDLE h, DWORD w, LPVOID p )
{
return TRUE;
}typedef struct ITestComWithC_Vtbl
{
BEGIN_INTERFACE
/* IUnknown */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )();
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )();
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(); STDMETHOD( set_TestProp )();
STDMETHOD( get_TestProp )();
STDMETHOD( TestMethod1 )();
END_INTERFACE
} ITestComWithC_Vtbl;typedef struct ITestComWithC_Impl_Simple
{
CONST_VTBL struct ITestComWithC_Vtbl* lpVtbl;
ULONG m_refcount;
long m_prop;
} ITestComWithC_Impl_Simple;STDMETHODIMP ITestComWithC_Impl_Simple_QI( IUnknown* This , REFIID riid , void** ppv )
{
if( !memcmp( &IID_IUnknown , riid , sizeof( GUID ) ) ||
!memcmp( &IID_ITestComWithC , riid , sizeof( GUID ) ) )
{
This->lpVtbl->AddRef( This );
*ppv = (void*)This;
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}STDMETHODIMP_(ULONG) ITestComWithC_Impl_Simple_Addref( ITestComWithC_Impl_Simple* This )
{
InterlockedIncrement( &This->m_refcount );
return This->m_refcount;
}STDMETHODIMP_(ULONG) ITestComWithC_Impl_Simple_Release( ITestComWithC_Impl_Simple* This )
{
if( 0 == InterlockedDecrement( &This->m_refcount ) )
{
CoTaskMemFree( This );
return 0;
}
return This->m_refcount;
}STDMETHODIMP ITestComWithC_Impl_Simple_set_Prop( ITestComWithC_Impl_Simple* This , long a )
{
This->m_prop = a;
return S_OK;
}STDMETHODIMP ITestComWithC_Impl_Simple_get_Prop( ITestComWithC_Impl_Simple* This , long* a )
{
if( !a ) return E_INVALIDARG;
*a = This->m_prop; return S_OK;
}STDMETHODIMP ITestComWithC_Impl_Simple_TestMethod1( ITestComWithC_Impl_Simple* This , long a , long b , long* c )
{
if( !c ) return E_INVALIDARG;
*c = a + b + This->m_prop;
return S_OK;
}static CONST_VTBL ITestComWithC_Vtbl vtbl_TestComWithC =
{
ITestComWithC_Impl_Simple_QI,
ITestComWithC_Impl_Simple_Addref,
ITestComWithC_Impl_Simple_Release,
ITestComWithC_Impl_Simple_set_Prop,
ITestComWithC_Impl_Simple_get_Prop,
ITestComWithC_Impl_Simple_TestMethod1
};HRESULT STDMETHODCALLTYPE SFI_QueryInterface(
IClassFactory __RPC_FAR * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
if( !memcmp( &IID_IClassFactory , riid , sizeof( GUID ) ) ||
!memcmp( &IID_IUnknown , riid , sizeof( GUID ) ) )
{
*ppvObject = This;
return S_OK;
}
return E_FAIL;
}
ULONG STDMETHODCALLTYPE __RPC_FAR SFI_AddRef(
IClassFactory __RPC_FAR * This)
{
return 1;
}
ULONG STDMETHODCALLTYPE __RPC_FAR SFI_Release (
IClassFactory __RPC_FAR * This)
{
return 1;
}
/* [local] */ HRESULT STDMETHODCALLTYPE __RPC_FAR SFI_CreateInstance(
IClassFactory __RPC_FAR * This,
/* [unique][in] */ IUnknown __RPC_FAR *pUnkOuter,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
if( pUnkOuter )
return E_FAIL;
if( !memcmp( riid , &IID_IUnknown , sizeof( GUID ) ) ||
!memcmp( riid , &IID_ITestComWithC , sizeof( GUID ) ) )
{
ITestComWithC_Impl_Simple *pThis = CoTaskMemAlloc( sizeof( ITestComWithC_Impl_Simple ) );
if( !pThis ) return E_OUTOFMEMORY;
pThis->lpVtbl = &vtbl_TestComWithC;
pThis->m_prop = 0;
pThis->m_refcount = 1;
*ppvObject = pThis;
return S_OK;
}
return E_FAIL;
}
/* [local] */ HRESULT STDMETHODCALLTYPE __RPC_FAR SFI_LockServer(
IClassFactory __RPC_FAR * This,
/* [in] */ BOOL fLock)
{
return S_OK;
}static IClassFactoryVtbl vtbl_IFC =
{
SFI_QueryInterface,
SFI_AddRef,
SFI_Release,
SFI_CreateInstance,
SFI_LockServer
};STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
static IClassFactory icf = { &vtbl_IFC }; if( !memcmp( rclsid , &CLSID_TestComWithC , sizeof( GUID ) ) &&
!memcmp( riid , &IID_IClassFactory , sizeof( GUID ) ) )
{
*ppv = &icf;
return S_OK;
} return CLASS_E_CLASSNOTAVAILABLE;
}STDAPI DllCanUnloadNow(void)
{
return S_FALSE;
}
import "ocidl.idl";[
uuid(03F1CF27-F63E-418f-8C64-F64FA20362DC),
version(1.0)
]
library libTestComWithC
{
importlib("stdole32.tlb");
importlib("stdole2.tlb"); [
object,
uuid(1BED467F-0934-4c7c-B657-472FEB0ED7F9),
pointer_default(unique)
]
interface ITestComWithC : IUnknown
{
HRESULT set_TestProp( long a );
HRESULT get_TestProp( [out,retval]long* valRet );
HRESULT TestMethod1 ( long a , long b , [out,retval]long* valRet );
}; [uuid(AA38E64D-7812-4ed1-B0CC-1BA4B117E12C)]
coclass TestComWithC
{
interface ITestComWithC;
};
};-----------------------------------------------------------------------不想写 RegSvr && UnRegSvr 两个函数, 用 reg 文件:
Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\CLSID\{AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}]
@="TestCOMWithC Object"[HKEY_CLASSES_ROOT\CLSID\{AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}\InprocServer32]
@="D:\\MyWork\\Demo\\TestCOMWithC\\Debug\\TestCOMWithC.dll"
"ThreadingModel"="Both"[HKEY_CLASSES_ROOT\CLSID\{AA38E64D-7812-4ed1-B0CC-1BA4B117E12C}\TypeLib]
@="{03F1CF27-F63E-418f-8C64-F64FA20362DC}"-----------------------------------------------------------------
.rc 里加上 1 TYPELIB "TestCOMWithC.tlb"
问个问题。
blog的密码和登录CSDN的密码一样吗?我怎么登录不了Blog.
这样定义接口:
typedef struct tag_IUnknownVtbl
{
HRESULT (__stdcall * pQueryInterface) (ComObject * this, REFIID iid, void ** ppvObject);
LONG (__stdcall * pAddRef) (ComObject * this);
LONG (__stdcall * pRelease) (ComObject * this);
} IUnknownVtbl;COM对象
typedef struct tag_ComObject
{
IUnknownVtbl * pVtbl;
/* 后面是自己定义的东西 */
} ComObject;取得COM对象:
IUnknown * GetObject()
{
ComObject * pObj = (ComObject *)malloc(sizeof(ComOBject));
pObj->pVtbl = (IUnknownVtbl *)malloc(sizeof(IUnknownVtbl));
pObj->pVtbl.pQueryInterface = xxx;
pObj->pVtbl.pAddRef = xxx;
pObj->pVtbl.pRelease = xxx;
return (IUnknown *)pObj;
}以上代码没有测试,仅供参考。