#include <ole2.h>
#include <comutil.h>
#include <comdef.h>
#include <string>
#include <vector>
#include <map>
using namespace std;
const wstring vtname(int vt)
{
static map<int, wstring> vtmap;
if (vtmap.size() == 0) {
vtmap[0] = L"VT_EMPTY";
vtmap[1] = L"VT_NULL";
vtmap[2] = L"short"; //L"VT_I2";
vtmap[3] = L"int"; //L"VT_I4";
vtmap[4] = L"float"; //L"VT_R4";
vtmap[5] = L"double"; //L"VT_R8";
vtmap[6] = L"Currency"; //L"VT_CY";
vtmap[7] = L"Date"; //L"VT_DATE";
vtmap[8] = L"String"; //L"VT_BSTR";
vtmap[9] = L"IDispatch*"; //L"VT_DISPATCH";
vtmap[10] = L"VT_ERROR";
vtmap[11] = L"bool"; //L"VT_BOOL";
vtmap[12] = L"variant"; //L"VT_VARIANT";
vtmap[13] = L"VT_UNKNOWN";
vtmap[14] = L"decimal"; //L"VT_DECIMAL";
vtmap[16] = L"byte"; //L"VT_I1";
vtmap[17] = L"ubyte"; //L"VT_UI1";
vtmap[18] = L"ushort"; //L"VT_UI2";
vtmap[19] = L"uint"; //L"VT_UI4";
vtmap[20] = L"long"; //L"VT_I8";
vtmap[21] = L"ulong"; //L"VT_UI8";
vtmap[22] = L"int"; //L"VT_INT";
vtmap[23] = L"uint"; //L"VT_UINT";
vtmap[24] = L"void"; //L"VT_VOID";
vtmap[25] = L"VT_HRESULT";
vtmap[26] = L"void*"; //L"VT_PTR";
vtmap[27] = L"VT_SAFEARRAY";
vtmap[28] = L"VT_CARRAY";
vtmap[29] = L"enum"; //L"VT_USERDEFINED";
vtmap[30] = L"String"; //L"VT_LPSTR";
vtmap[31] = L"String"; //L"VT_LPWSTR";
vtmap[36] = L"VT_RECORD";
vtmap[8192] = L"VT_ARRAY";
vtmap[16384] = L"VT_BYREF";
vtmap[32768] = L"VT_RESERVED";
vtmap[64] = L"VT_FILETIME";
vtmap[65] = L"VT_BLOB";
vtmap[66] = L"VT_STREAM";
vtmap[67] = L"VT_STORAGE";
vtmap[68] = L"VT_STREAMED_OBJECT";
vtmap[69] = L"VT_STORED_OBJECT";
vtmap[70] = L"VT_BLOB_OBJECT";
vtmap[71] = L"VT_CF";
vtmap[72] = L"VT_CLSID";
vtmap[4096] = L"VT_VECTOR";
vtmap[4095] = L"VT_TYPEMASK";
vtmap[65535] = L"VT_ILLEGAL";
}
return vtmap[vt];
}
struct FUNC {
int rettype;
vector<int> argtypes;
vector<wstring> fnames;
map<int, _variant_t> defs;
int invkind;
wstring tostr()
{
int i;
int j;
wstring ret;
if (this->invkind == INVOKE_FUNC) {
ret.append(vtname(rettype));
ret.append(L" ");
ret.append(fnames[0]);
if (fnames.size() == 1)
ret.append(L"()");
else {
for (j = 1; j < fnames.size(); j++) {
if (j == 1)
ret.append(L"(");
ret.append(vtname(argtypes[j-1]));
ret.append(L" ");
ret.append(fnames[j]);
if (defs.find(j - 1) != defs.end()) {
ret.append(L" = ");
ret.append((wchar_t*)(_bstr_t)defs[j - 1]);
}
ret.append(j == fnames.size() - 1 ? L")" : L", ");
}
}
}
else {
ret.append(vtname(rettype));
ret.append(L" ");
ret.append(fnames[0]);
if (invkind == INVOKE_PROPERTYGET)
ret.append(L"{read}");
if (invkind == INVOKE_PROPERTYPUT) {
ret.append(L"{write ");
ret.append(vtname(argtypes[0]));
ret.append(L"}");
}
if (invkind == INVOKE_PROPERTYPUTREF) {
ret.append(L"{write byref ");
ret.append(vtname(argtypes[0]));
ret.append(L"}");
}
}
return ret;
}
};
int main(int argc, char* argv[])
{
printf("Hello World!/n");
CoInitialize(NULL);
IDispatch *disp = NULL;
CLSID clsid;
ITypeInfo *ptinfo;
TYPEATTR * pTypeAttr;
HRESULT hr;
FUNCDESC * pFuncDesc;
BSTR names[255];
BSTR name, doc;
unsigned int nnames;
vector<FUNC> funcs;
int i;
int j;
hr = CLSIDFromProgID(L"ADODB.Connection", &clsid);
hr = CoCreateInstance(clsid, NULL, CLSCTX_SERVER, // 进程或DLL
IID_IDispatch, (void **)&disp);
disp->GetTypeInfo(0, GetUserDefaultLCID(), &ptinfo);
hr = ptinfo->GetTypeAttr(&pTypeAttr);
funcs.resize(pTypeAttr->cFuncs);
for (i = 0; i < pTypeAttr->cFuncs; i++) {
ptinfo->GetFuncDesc(i, &pFuncDesc);
// 调用方式
funcs[i].invkind = pFuncDesc->invkind;
// 返回类型
funcs[i].rettype = pFuncDesc->elemdescFunc.tdesc.vt;
// 函数名和参数名
ptinfo->GetNames(pFuncDesc->memid, names, 255, &nnames);
for (j = 0; j < nnames; j++) {
funcs[i].fnames.push_back(names[j]);
SysFreeString(names[j]);
}
// 参数类型和默认值
for (j = 0; j < pFuncDesc->cParams; j++) {
funcs[i].argtypes.push_back(pFuncDesc->lprgelemdescParam[j].tdesc.vt);
if (pFuncDesc->lprgelemdescParam[j].idldesc.wIDLFlags & PARAMFLAG_FHASDEFAULT
&& pFuncDesc->lprgelemdescParam[j].paramdesc.pparamdescex) {
funcs[i].defs[j] = pFuncDesc->lprgelemdescParam[j].paramdesc.pparamdescex->varDefaultValue;
}
}
ptinfo->ReleaseFuncDesc(pFuncDesc);
}
ptinfo->ReleaseTypeAttr(pTypeAttr);
ptinfo->Release();
disp->Release();
for (i = 0; i < funcs.size(); i++) {
wprintf(L"%s/n", funcs[i].tostr().c_str());
}
CoUninitialize();
return 0;
}