-
COM DLL Functions in C
hi i have this dll with no documentation on it, i think some kid wrote it in VB cause it uses BSTR for text parameters on the function inside it and a long type for a socket to pass to it... can someone tell me what to pass to CoCreateInstance as the CLSID and IID, i tried doing:
DEFINE_GUID(AOLLib_CLSID, 0xC903F65A, 0x4ec0, 0x43a3, 0xb1, 0x99, 0x1f, 0x67, 0x1e, 0xa1, 0xbf, 0x61);
DEFINE_GUID(AOLLib_IID, 0xB797378B, 0x3113, 0x4908, 0xb2, 0x03, 0xba, 0xf4, 0x9e, 0xe2, 0xe5, 0xd1);
then
IAOLSecurity *atbl = NULL;
if ( S_OK != (OleInitialize(NULL)) )
exit(0);
printf("loaded\n");
if( !(hRes = CoCreateInstance( &AOLLib_IID, NULL, CLSCTX_INPROC_SERVER,&AOLLib_CLSID, &atbl) ) )
{
printf("nope\n");
OleUninitialize();
exit( 0 );
}
printf("instance created\n");
ok = SysAllocString(L"test");
pw = SysAllocString(L"test");
txt = SysAllocString(L"ok.txt");
printf("allocated\n");
printf("yeah %d\n", socko);
atbl->lpVtbl->Login(atbl, socko, ok, pw, txt);
but it crashes at with an access violation
atbl->lpVtbl->Login(atbl, socko, ok, pw, txt);
if everything works after CoCreateInstance that means the DLL was loaded correctly, right?
socko is
long socko;
socko = socket(AF_INET, SOCK_STREAM, 0);
i made it long to comply witht he type in the function inside the typelib header which im about to paste
can someone please tell me what im doing wrong?
Code:
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 5.01.0164 */
/* at Tue May 31 01:50:18 2005
*/
/* Compiler settings for C:\idl\aollib.idl:
Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext
error checks: allocation ref bounds_check enum stub_data
*/
//@@MIDL_FILE_HEADING( )
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 440
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __aollib_h__
#define __aollib_h__
#ifdef __cplusplus
extern "C"{
#endif
/* Forward Declarations */
#ifndef __IAOLSecurity_FWD_DEFINED__
#define __IAOLSecurity_FWD_DEFINED__
typedef interface IAOLSecurity IAOLSecurity;
#endif /* __IAOLSecurity_FWD_DEFINED__ */
#ifndef __AOLSecurity_FWD_DEFINED__
#define __AOLSecurity_FWD_DEFINED__
#ifdef __cplusplus
typedef class AOLSecurity AOLSecurity;
#else
typedef struct AOLSecurity AOLSecurity;
#endif /* __cplusplus */
#endif /* __AOLSecurity_FWD_DEFINED__ */
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t);
void __RPC_USER MIDL_user_free( void __RPC_FAR * );
#ifndef __AOLLib_LIBRARY_DEFINED__
#define __AOLLib_LIBRARY_DEFINED__
/* library AOLLib */
/* [helpstring][version][uuid] */
EXTERN_C const IID LIBID_AOLLib;
#ifndef __IAOLSecurity_INTERFACE_DEFINED__
#define __IAOLSecurity_INTERFACE_DEFINED__
/* interface IAOLSecurity */
/* [object][oleautomation][dual][uuid] */
EXTERN_C const IID IID_IAOLSecurity;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("B797378B-3113-4908-B203-BAF49EE2E5D1")
IAOLSecurity : public IDispatch
{
public:
virtual /* [id] */ HRESULT STDMETHODCALLTYPE Login(
/* [in] */ long lSocket,
/* [in] */ BSTR bstrUsername,
/* [in] */ BSTR bstrPassword,
/* [defaultvalue][optional][in] */ BSTR bstrCertFileName = L"") = 0;
};
#else /* C style interface */
typedef struct IAOLSecurityVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
IAOLSecurity __RPC_FAR * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
IAOLSecurity __RPC_FAR * This);
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
IAOLSecurity __RPC_FAR * This);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
IAOLSecurity __RPC_FAR * This,
/* [out] */ UINT __RPC_FAR *pctinfo);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
IAOLSecurity __RPC_FAR * This,
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
IAOLSecurity __RPC_FAR * This,
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
IAOLSecurity __RPC_FAR * This,
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
/* [out] */ VARIANT __RPC_FAR *pVarResult,
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr);
/* [id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Login )(
IAOLSecurity __RPC_FAR * This,
/* [in] */ long lSocket,
/* [in] */ BSTR bstrUsername,
/* [in] */ BSTR bstrPassword,
/* [defaultvalue][optional][in] */ BSTR bstrCertFileName);
END_INTERFACE
} IAOLSecurityVtbl;
interface IAOLSecurity
{
CONST_VTBL struct IAOLSecurityVtbl __RPC_FAR *lpVtbl;
};
#ifdef COBJMACROS
#define IAOLSecurity_QueryInterface(This,riid,ppvObject) \
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
#define IAOLSecurity_AddRef(This) \
(This)->lpVtbl -> AddRef(This)
#define IAOLSecurity_Release(This) \
(This)->lpVtbl -> Release(This)
#define IAOLSecurity_GetTypeInfoCount(This,pctinfo) \
(This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
#define IAOLSecurity_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
(This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
#define IAOLSecurity_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
(This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
#define IAOLSecurity_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
(This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
#define IAOLSecurity_Login(This,lSocket,bstrUsername,bstrPassword,bstrCertFileName) \
(This)->lpVtbl -> Login(This,lSocket,bstrUsername,bstrPassword,bstrCertFileName)
#endif /* COBJMACROS */
#endif /* C style interface */
/* [id] */ HRESULT STDMETHODCALLTYPE IAOLSecurity_Login_Proxy(
IAOLSecurity __RPC_FAR * This,
/* [in] */ long lSocket,
/* [in] */ BSTR bstrUsername,
/* [in] */ BSTR bstrPassword,
/* [defaultvalue][optional][in] */ BSTR bstrCertFileName);
void __RPC_STUB IAOLSecurity_Login_Stub(
IRpcStubBuffer *This,
IRpcChannelBuffer *_pRpcChannelBuffer,
PRPC_MESSAGE _pRpcMessage,
DWORD *_pdwStubPhase);
#endif /* __IAOLSecurity_INTERFACE_DEFINED__ */
EXTERN_C const CLSID CLSID_AOLSecurity;
#ifdef __cplusplus
class DECLSPEC_UUID("C903F65A-4EC0-43A3-B199-1F671EA1BF61")
AOLSecurity;
#endif
#endif /* __AOLLib_LIBRARY_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif
-
have you registered the dll on you PC? (ie with regsvr32.exe)
have you imported the dll's .tlb file?
ie
#import "AOLSecurity.tlb" named_guids raw_interfaces_only
-
i regsvrd the dll...how do i do #import "AOLSecurity.tlb" named_guids raw_interfaces_only
i dont have a .tlb i have a .idl
-
You have your clsid and iid mixed up. Also, CoCreateInstance returns 0 (NOERROR) on success so you had your error checking reversed. Yoiu should check the success or failure of a COM function with the SUCCEEDED and FAILED macros.
Code:
HRESULT hr;
hr = CoCreateInstance( &AOLLib_CLSID, NULL, CLSCTX_INPROC_SERVER, &AOLLib_IID, &atbl );
if(FAILED(hr))
{
printf("nope, failed with error %08x\n", hr);
OleUninitialize();
exit( 0 );
}
else
{
printf("instance created\n");
ok = SysAllocString(L"test");
pw = SysAllocString(L"test");
txt = SysAllocString(L"ok.txt");
printf("allocated\n");
printf("yeah %d\n", socko);
hr = atbl->lpVtbl->Login(atbl, socko, ok, pw, txt);
if (FAILED(hr))
{
printf("Failed to login with error %08x\n", hr);
}
}
You will find this difficult without documentation. For example, does the socket have to be connected before being passed to the Login function?
You may be interested in DispHelper which makes it easier to call COM objects from C or C++.
-
thank you very much anonytmouse!