我需要使用R工具中包含的gcc編譯器(R爲Windows的統計程序)來編譯我的一些代碼,問題是我需要使用IDispatch在我創建一個訪問COM對象的方法的代碼中,並且gcc編譯器不支持我正在使用的大部分代碼,這基本上就是C++代碼。如何在純C中使用IDispatch來調用COM對象
所以我的問題是如何在C中使用IDispatch創建COM對象,而不必依賴於MFC,.NET,C#,WTL或ATL。我相信如果我這樣做,我將能夠毫無問題地編譯我的代碼。
我需要使用R工具中包含的gcc編譯器(R爲Windows的統計程序)來編譯我的一些代碼,問題是我需要使用IDispatch在我創建一個訪問COM對象的方法的代碼中,並且gcc編譯器不支持我正在使用的大部分代碼,這基本上就是C++代碼。如何在純C中使用IDispatch來調用COM對象
所以我的問題是如何在C中使用IDispatch創建COM對象,而不必依賴於MFC,.NET,C#,WTL或ATL。我相信如果我這樣做,我將能夠毫無問題地編譯我的代碼。
通常,C++ IDispatch接口只是一個函數指針表。 在C,它看起來是這樣的:
typedef struct {
HRESULT(*pQueryInterface)(void* this, REFIID riid, void **ppvObject);
ULONG(*pAddRef)(void* this);
ULONG(*pRelease)(void* this);
HRESULT(*pGetTypeInfoCount)(void* this, unsigned int* pctInfo);
HRESULT(*pGetTypeInfo)(void* this, unsigned int iTInfo,LCID lcid, ITypeInfo** ppTInfo);
HRESULT(*pGetIDsOfNames)(void* this, REFIID riid, OLECHAR** rgszNames, unsigned int cNames, LCID lcid, DISPID* rgDispId);
HRESULT(*pInvoke)(void* this, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, unsigned int* puArgErr);
} IDispatch_in_C;
需要注意的是每個方法都有一個this指針作爲第一個參數,那你就需要定義多種類型,如ITypeInfo的,REFIID,DISPID等,等等。
所以,它是一個很大的任務。但有可能在純C中創建C++接口。
您也可以使用disphelper庫。
請注意,您需要確保您的調用約定匹配,否則您的參數傳遞順序和堆棧清理將無法正常工作。確保這些方法被聲明爲使用'stdcall'調用約定。 – 2009-06-03 20:50:18
這並不能很好地解釋C++中的IDispatch使用此調用的事實,因此它通過ecx傳遞,而不是在堆棧上;而在C中它通過這個通過棧而不是ecx;而CoCreateInstance不關心你是否使用C或C++。不明白爲什麼其中一個版本不會因錯誤的調用約定而失敗。同樣如上所述,您的示例默認爲cdecl,而com期望stdcall,因此您最終清理堆棧的次數會有效地破壞堆棧。 – Dmitry 2018-02-12 22:44:19