1
INTERFACE
in COM
nonezerok@gmail.com
저자의 동의 없이 본 문서 일부 또는 전체의 무단복제를 불허합니다.
2
a.exe b.dll
it is possible
extern “C” void __stdcall Fx();
Dynamic Link Library
(Local Procedure Call)
3
a.exe b.dll
Is it possible ?
Invoking functions of an Object
4
a.exe b.dll
No !!!
encapsulated and information hidden
Invoking functions of an Object
5
a.exe b.dll
interface
however,
How to achieve it ?
make a window;
call it an interface
6
Virtual Function Technique
class A 
{ int d1;
int show() { cout << “A” << endl; };
} ;
class B: public A
{ int d2;
int show() { cout << “B” << endl; };
} ;
void main()
{ A  a, *pA;
B  b, *pB;
pA = &b;
pA‐>show(); // A or B ? What is your expectation ?
}
7
class A 
{ int d1;
virtual int show() { cout << “A” << endl; };
} ;
class B: public A
{ int d2;
int show() { cout << “B” << endl; };
} ;
void main()
{ A  a, *pA;
B  b, *pB;
pA = &b;
pA‐>show();
// before and after adding virtual
cout << sizeof(a) << endl;
}
How about adding another virtual function ?
virtual int draw() in the class A
8
vPtr
d1
d2
A::show()
B::show()
A::draw()
B::draw()
pA
(&b)
virtual function
table
dynamic binding
Note: we can invoke B’s functions using A
9
Conceptual View of Interface
a.exe b.dll
public
10
struct IX // pure abstract class (here, public class)
{ virtual void __stdcall Fx1() = 0; // pure virtual function
virtual void __stdcall Fx2() = 0; //  abstract class
};
class CA: public IX
{ void __stdcall Fx1() { cout << “Fx1” << endl; };
void __stdcall Fx2() { cout << “Fx2” << endl; };
};
void main()
{ CA* pA = new CA;
IX* pX = (IX*)pA;
pX‐>Fx1();
delete pA;
}
• Using the virtual function technique, we can
indirectly invoke the function of a COM object
• Public Pure Abstract Class
Definition of Interface
11
#define interface struct
interface IX // pure abstract class (here, public class)
{ virtual void __stdcall Fx1() = 0; // pure virtual function
virtual void __stdcall Fx2() = 0; //  abstract class
};
class CA: public IX
{ void __stdcall Fy1() { cout << “Fy1” << endl; };
void __stdcall Fy2() { cout << “Fy2” << endl; };
};
void main()
{ CA* pA = new CA;
IX* pX = (IX*)pA;
pX‐>Fx1();
delete pA;
}
Can this main function be a client-side code ?
12
interface IY
{ virtual void __stdcall Fy1() = 0;
virtual void __stdcall Fy2() = 0;
};
class CA: public IX, public IY
{ void __stdcall Fy1() { cout << “Fy1” << endl; };
void __stdcall Fy2() { cout << “Fy2” << endl; };
};
IX* CreateInstance()
{ CA* pA = new CA;
return pA;
}
void main()
{ IX* pX = CreateInstance();
pX‐>Fx1();
IY* pY = (IY*)pX; // ?
pY‐>Fy1(); // ?
delete pX;
}
What for adding another interface ?
13
interface IU { };
interface IX: IU { … };
interface IY: IU { … };
class CA: public IX, public IY
{ void __stdcall Fx1() { cout << “Fx1” << endl; };
void __stdcall Fx1() { cout << “Fx2” << endl; };
void __stdcall Fy1() { cout << “Fy1” << endl; };
void __stdcall Fy2() { cout << “Fy2” << endl; };
} ;
IU* CreateInstance()
{ CA* pA = new CA;
return (IX*)pA;
}
void main()
{ IU* pU = CreateInstance();
IX* pX = (IX*)pU;
pX‐>Fx1(); // ?
IY* pY = (IY*)pU; 
pY‐>Fy1();  // ?
delete pX;
}
14
interface IU 
{ virtual bool __stdcall QI(int id, void** ppv) = 0;
};
interface IX: IU { … };
interface IY: IU { … };
class CA: public IX, public IY
{ bool __stdcall QI(int id, void** ppv)
{ if (id == IID_IX) *ppv = (IX*) this;
else if (id == IID_IY) *ppv = (IY*) this;
else { *ppv = NULL; return false; };
return true;
}
};
void main()
{ IU* pU = CreateInstance();
IX* pX;  pU‐>QI(IID_IX, (void**)&pX);  pX‐>Fx1();
IY* pY;  pU‐>QI(IID_IY, (void**)&pY);  pY‐>Fy1(); 
delete pX;
}
15
Client for DLL Server
typedef IUnknown* (*FUNCPTR)();
void main()
{
HINSTANCE hDll;
hDll = LoadLibary(“d:comserver.dll”);
FUNCPTR CreateInstance 
= (FUNCPTR)::GetProcAddress (hDll, ʺCreateInstanceʺ);
IU* pU = CreateInstance();
IX* pX;  pU‐>QI(IID_IX, (void**)&pX);  pX‐>Fx1();
IY* pY;  pU‐>QI(IID_IY, (void**)&pY);  pY‐>Fy1(); 
delete pX;
FreeLibrary(hDll);
}
path
If the path is changed ?

interface