Com call Method

Source: Internet
Author: User

I. Dynamic call:

Early binding means that the type has been determined during the compilation period. After compilationCodeExecution efficiency is very high; late binding determines the type only at runtime. Late binding requires determining the type at runtime, so the efficiency is relatively low, but it brings great flexibility. I think dynamic calling is a specific form of late binding, that is, calling the functions in the DLL without the header file and Lib.
Currently, the plug-in system software developed based on ATL mostly adopts the former, that is, the. h and _ I. c files compiled by IDL. This method is sometimes rigid and lacks dynamic mechanisms. In fact, any of the technologies described below can be used to construct your own plug-in system and can be designed flexibly.
The following are the three dynamic call methods I know (the example is based on vs2005 ):
1. dll function call: (obtain the function address)
HypothesisDllfunc. dllThere is a function: int add (int A, int B). The procedure for calling the client is as follows:

// Load dynamic library
  Hmodule = Loadlibrary (_ T ( " Dllfunc. dll " ));
If (Hmodule)
{
// Get function address
  Fnadd = (Lpfunc) getprocaddress (hmodule, " Add " );
If (Fnadd)
{
 // Call a function 
 Iret = Fnadd ( 2 , 4 );
Printf ( " Result is % d " , Iret );

// Release a dynamic library
  Freelibrary (hmodule );
Hmodule = NULL;
}


2. COM component function call (invoke of idispatch)
Assume that there is a component whose progid is "atlfunc. mymath.1". The attributes and interface methods are as follows:

Interface Imymath: idispatch {
[Propget, ID (1), Helpstring ("Property result")] Hresult result ([Out, Retval] Long*Pval );
[Propput, ID (1), Helpstring ("Property result")] Hresult result ([In] Long newval );
[ID (2), Helpstring ("Method Add")] Hresult add (long a, long B ,[Out, Retval] Long*PC );
} ;

The procedure for calling a client is as follows:

// Initialize the com Library
Coinitialize (null );
// Create component based on progid
HR = Pimymath. cocreateinstance (_ T ( " Atlfunc. mymath.1 " ));
If (Succeeded (HR ))
{
// Obtain the dispid of the add function.
HR = Pimymath -> Getidsofnames (iid_null, & Szmember, 1 , Locale_user_default, & Dispid );
If (HR = S_ OK)
{
Pvarsin =   New Ccomvariant [ 2 ];
Pvarsin [ 0 ]. Vt = Vt_i4;
Pvarsin [ 0 ]. Intval =   2 ;
Pvarsin [ 1 ]. Vt = Vt_i4;
Pvarsin [ 1 ]. Intval =   4 ;
Dispparams dispparam =   {Pvarsin, null,2,0} ;
// Call the Add function
Variantinit ( & Vtout );
HR = Pimymath -> Invoke (dispid, iid_null, locale_user_default, dispatch_method, & Dispparam, & Vtout, null, null );
If (Succeeded (HR ))
{
Printf ("% D", Vtout. intval );
}
Variantclear ( & Vtout );
Delete [] pvarsin;
Pvarsin = NULL;
}
// In fact, if we know the interface method or the dispid of the attribute, we can directly call it through dispid.
Variantinit ( & Vtout );
Dispparams dispparam =   {Null, null,0,0} ;
HR = Pimymath -> Invoke ( 1 , Iid_null, locale_user_default, dispatch_propertyget, & Dispparam, & Vtout, null, null );
If (Succeeded (HR ))
{
Printf ("% D", Vtout. intval );
}
Variantclear ( & Vtout );
}
// Release the COM component before couninitialize. Otherwise, the component may be released after the com library is uninstalled.
Pimymath = NULL;
// Release com Library
Couninitialize ();


3... NET Component function call: (reflection technology)

Assume a CLR class libraryProgramThere is a class mymath in the set that contains the int add (int A, int B) method. The call steps on the client are as follows:

Try
{
// Load assembly
Passembly = Assembly: load (L " Clrfunc " );
// Obtains the clrfunc. mymath type in a dataset.
Ptype = Passembly -> GetType (L " Clrfunc. mymath " , True , True );
// Obtain method information
PMI = Ptype -> Getmethod (L " Add " );
// Create a clrfunc. mymath instance
Pobject = Activator: createinstance (ptype );
P [ 0 ] =   2 ;
P [ 1 ] =   4 ;
// Call Method
Iret = Safe_cast < Int32 ^> (PMI -> Invoke (pobject, p ));
System: Console: writeline (iret );
}
Catch (Exception ^ Exp)
{
System: Console: writeline (exp->Message );
}


The so-called plug-in technology only specifies a set of interfaces on the main program. All the load modules that follow the interfaces are plug-ins. The main program can use the above method to load any DLL and call the method function. As long as the function is satisfied, the plug-in system is no longer limited to the COM interface level, A plug-in can be implemented in the above three forms.

 

Ii. Other basic methods:

 

Void cuse1dlg: onbnclickedbutton1 ()

{

: Coinitialize (null );

 

Iunknown * punk = NULL;

Ifun * pfun = NULL;

Hresult hr;

 

Try

{

HR =: cocreateinstance (

Clsid_fun,

Null,

Clsctx_inproc_server, // load in the way of In-process component DLL

Iid_iunknown, // you want to obtain the iunknown interface pointer

(Lpvoid *) & punk );

If (failed (HR) Throw (_ T ("not registered? "));

 

HR = punk-> QueryInterface (// obtain other interface pointers from iunknown

Iid_ifun, // you want to obtain the ifun interface pointer

(Lpvoid *) & pfun );

If (failed (HR) Throw (_ T ("actually no interface? "));

 

Long nsum;

HR = pfun-> Add (1, 2, & nsum); // ifun: add ()

If (succeeded (HR ))

{

Cstring smsg;

Smsg. Format (_ T ("1 + 2 = % d"), nsum );

Afxmessagebox (smsg );

}

 

BSTR S1 =: sysallocstring (L "hello ");

BSTR S2 =: sysallocstring (L "world ");

BSTR S3 = NULL;

 

HR = pfun-> CAT (S1, S2, & S3); // ifun: CAT ()

If (succeeded (HR ))

{

Cstring smsg (S3 );

Afxmessagebox (smsg );

}

 

// Ifun: CAT () The last parameter is the [out] direction attribute, so the caller needs to release

If (S3): sysfreestring (S3 );

}

Catch (lpctstr lperr)

{

Afxmessagebox (lperr );

}

 

If (punk) punk-> release ();

If (pfun) pfun-> release ();

 

: Couninitialize ();

}

 

// Contains the header file required to use ccombstr

# Include <atlbase. h>

 

Void cuse1dlg: onbnclickedbutton2 ()

{

: Coinitialize (null );

 

Ifun * pfun = NULL;

Hresult hr;

 

Try

{

HR =: cocreateinstance (

Clsid_fun,

Null,

Clsctx_inproc_server,

Iid_ifun, // get the ifun interface pointer directly without passing through iunknown

(Lpvoid *) & pfun );

If (failed (HR) Throw (_ T ("not registered, right? Or no interface? "));

 

Long nsum;

HR = pfun-> Add (1, 2, & nsum );

If (succeeded (HR ))

{

Cstring smsg;

Smsg. Format (_ T ("1 + 2 = % d"), nsum );

Afxmessagebox (smsg );

}

 

Ccombstr S1 ("hello"); // no longer using APIs to operate BSTR

Ccombstr S2 ("world"); // It is relatively simple to use ccombstr, and

Ccombstr S3; // The biggest benefit is that we don't have to release it ourselves.

 

HR = pfun-> CAT (S1, S2, & S3 );

If (succeeded (HR ))

{

Cstring smsg (S3 );

Afxmessagebox (smsg );

}

}

Catch (lpctstr lperr)

{

Afxmessagebox (lperr );

}

 

If (pfun) pfun-> release ();

 

: Couninitialize ();

}

 

2

 

Void cuse2dlg: onbnclickedbutton3 () // ccomptr example

{

// The COM Initialization is called using the afxoleinit () function and placed in cuse2app: initinstance.

 

Ccomptr <iunknown> spunk; // defines the iunknown smart pointer

Ccomptr <ifun> spfun; // defines the ifun smart pointer

Hresult hr;

 

Try

{

// You can use CLSID to start the component or progid

HR = spunk. cocreateinstance (clsid_fun );

If (failed (HR) Throw (_ T ("no registered component? "));

 

HR = spunk. QueryInterface (& spfun );

If (failed (HR) Throw (_ T ("actually no interface? "));

 

Long nsum;

HR = spfun-> Add (1, 2, & nsum );

If (succeeded (HR ))

{

Cstring smsg;

Smsg. Format (_ T ("1 + 2 = % d"), nsum );

Afxmessagebox (smsg );

}

 

Ccombstr S1 ("hello"), S2 ("world"), S3;

HR = spfun-> CAT (S1, S2, & S3 );

If (succeeded (HR ))

{

Cstring smsg (S3 );

Afxmessagebox (smsg );

}

}

Catch (lpctstr lperr)

{

Afxmessagebox (lperr );

}

 

// The biggest benefit of Smart interface pointers is that we do not have to release them.

}

 

Void cuse2dlg: onbnclickedbutton4 () // ccomqiptr example

{

Ccomptr <iunknown> spunk; // smart pointer iunknown

Ccomqiptr <ifun> spfun; // smart pointer ifun

Hresult hr;

 

Try

{

// Use progid to start the component

HR = spunk. cocreateinstance (L "simple2.fun. 1 ");

If (failed (HR) Throw (_ T ("not registered? "));

 

Spfun = spunk; // ccomqiptr will automatically call QueryInterface

If (! Spfun) Throw (_ T ("is there no interface? "); // Whether the operation is successful or not, the non-null value can be determined.

 

Long nsum;

HR = spfun-> Add (1, 2, & nsum );

If (succeeded (HR ))

{

Cstring smsg;

Smsg. Format (_ T ("1 + 2 = % d"), nsum );

Afxmessagebox (smsg );

}

 

Ccombstr S1 ("hello"), S2 ("world"), S3;

HR = spfun-> CAT (S1, S2, & S3 );

If (succeeded (HR ))

{

Cstring smsg (S3 );

Afxmessagebox (smsg );

}

}

Catch (lpctstr lperr)

{

Afxmessagebox (lperr );

}

 

}

 

Void cuse2dlg: onbnclickedbutton5 () // no longer passes iunknown

{

Ccomqiptr <ifun, & iid_ifun> spfun; // defines the ifun smart pointer.

Hresult hr;

 

Try

{

HR = spfun. cocreateinstance (L "simple2.fun. 1 ");

If (failed (HR) Throw (_ T ("no component registered or interface found "));

 

Long nsum;

HR = spfun-> Add (1, 2, & nsum );

If (succeeded (HR ))

{

Cstring smsg;

Smsg. Format (_ T ("1 + 2 = % d"), nsum );

Afxmessagebox (smsg );

}

 

Ccombstr S1 ("hello"), S2 ("world"), S3;

HR = spfun-> CAT (S1, S2, & S3 );

If (succeeded (HR ))

{

Cstring smsg (S3 );

Afxmessagebox (smsg );

}

}

Catch (lpctstr lperr)

{

Afxmessagebox (lperr );

}

}

 

3

 

Void cuse3dlg: onbnclickedbutton6 () // release smart pointer

{

//: Coinitialize (null); // If COM Initialization is performed here, pay attention to the release of smart pointers.

 

Ccomqiptr <ifun, & iid_ifun> spfun;

 

Hresult hR = spfun. cocreateinstance (clsid_fun );

Assert (succeeded (HR ));

// For the sake of simplicity, if is no longer used to judge hresult. Ifun: add () is not called either.

 

Ccombstr S1 ("hello"), S2 ("world"), S3;

HR = spfun-> CAT (S1, S2, & S3 );

Assert (succeeded (HR ));

Cstring smsg (S3 );

Afxmessagebox (smsg );

 

// Spfun-> release (); // a big mistake !!!

// Spfun. Release (); // Positive Solution

 

//: Couninitialize ();

}

4

 

Void cuse4dlg: onbnclickedbutton7 () // # Use of Import

{

/*************************************** *******************

1. Use afxoleinit () in cuse4app: initinstance () for initialization

2. Open the stdafx. h file, insert # import, and compile

Generate smart pointer packaging for. tlh and. tlh.

3. # using no_namespace for Import means no namespace is used

4. The smart pointer is packaged in the form of ixxxptr. xxx indicates the interface name.

**************************************** *******************/

Ifunptr spfun;

Hresult hR = spfun. createinstance (L "simple2.fun. 1"); // use progid

// Hresult hR = spfun. createinstance (_ uuidof (fun); // use CLSID

Assert (succeeded (HR ));

 

Try

{

Long nsum = spfun-> Add (1, 2 );

 

Cstring smsg;

Smsg. Format (_ T ("1 + 2 = % d"), nsum );

Afxmessagebox (smsg );

 

_ Bstr_t scat = spfun-> CAT (_ T ("hello"), _ T ("world "));

Afxmessagebox (SCAT );

}

Catch (_ com_error & E)

{

// Detailed error information can be obtained here

// Details about the isupporterrorinfo interface in the future

// E. Description ();

// E. errormessage ();

// E. errorinfo ();

//......

E; // because E is not used, add this line to cancel the compilation warning.

Afxmessagebox (_ T ("error "));

}

}

 

 

5

 

Void cuse5dlg: onbnclickedbutton8 ()

{

// Because # import in stdafx. h does not use no_namespace, The namespace must be used.

// The namespace is simple2lib, which is specified by the component IDL file library.

Try

{

// This time, the component is started using the constructor of the smart pointer, which is easy to write.

// But it also has disadvantages, because if it fails, you do not know the cause of the error.

 

// Simple2lib: ifunptr spfun (L "simple2.fun. 1"); // progid

Simple2lib: ifunptr spfun (_ uuidof (simple2lib: Fun); // CLSID Method

 

Long nsum = spfun-> Add (1, 2 );

 

Cstring smsg;

Smsg. Format (_ T ("1 + 2 = % d"), nsum );

Afxmessagebox (smsg );

 

_ Bstr_t scat = spfun-> CAT (_ T ("hello"), _ T ("world "));

Afxmessagebox (SCAT );

}

Catch (_ com_error & E)

{

E;

Afxmessagebox (_ T ("error "));

}

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.