Calling a function directly via VTable.
-
Hey everybody. I am trying to a call a virtual function directly from the VTable. I created a COM component using the visual studio (ATL Simple object).
STDMETHODIMP Ctest_com::print_me(BSTR txt) { OutputDebugString(txt); return S_OK; }
Now, I am trying this use the COM, but calling the function via VTable:// signature of print_me. // STDMETHODCALLTYPE is __stdcall typedef HRESULT (STDMETHODCALLTYPE* ptr_print)(BSTR); int _tmain(int argc, _TCHAR* argv[]) { CoInitialize(NULL); cpp_com_testLib::Itest_com* comobj; HRESULT hr = CoCreateInstance(__uuidof(cpp_com_testLib::test_com), NULL, CLSCTX_INPROC_SERVER, __uuidof(cpp_com_testLib::Itest_com), (void**)&comobj); int* vptr = (int*)(comobj); vptr = (int*)*vptr; // gets a pointer to the VTABLE int* vproc0 = (int*)vptr[0]; // get a point to first function in VTable ... ... ... int* vproc7 = (int*)vptr[7]; // pointer to print_me() ! ptr_print p = (ptr_print)vproc7; // cast to the function pointer. _bstr_t bstr(_T("MY TEXT!")); p(bstr); // <--- happens the problem. comobj->Release(); CoUninitialize(); return 0; }
NOW, here is THE PROBLEM. When I call "p(bstr)" I do get to "print_me()", BUT the parameter "txt" is not passed to the function correctly (I sends a whole different address, so it is a BAD POINTER). ANY IDEAS???? THANKS A LOT IN ADVANCE! -
Hey everybody. I am trying to a call a virtual function directly from the VTable. I created a COM component using the visual studio (ATL Simple object).
STDMETHODIMP Ctest_com::print_me(BSTR txt) { OutputDebugString(txt); return S_OK; }
Now, I am trying this use the COM, but calling the function via VTable:// signature of print_me. // STDMETHODCALLTYPE is __stdcall typedef HRESULT (STDMETHODCALLTYPE* ptr_print)(BSTR); int _tmain(int argc, _TCHAR* argv[]) { CoInitialize(NULL); cpp_com_testLib::Itest_com* comobj; HRESULT hr = CoCreateInstance(__uuidof(cpp_com_testLib::test_com), NULL, CLSCTX_INPROC_SERVER, __uuidof(cpp_com_testLib::Itest_com), (void**)&comobj); int* vptr = (int*)(comobj); vptr = (int*)*vptr; // gets a pointer to the VTABLE int* vproc0 = (int*)vptr[0]; // get a point to first function in VTable ... ... ... int* vproc7 = (int*)vptr[7]; // pointer to print_me() ! ptr_print p = (ptr_print)vproc7; // cast to the function pointer. _bstr_t bstr(_T("MY TEXT!")); p(bstr); // <--- happens the problem. comobj->Release(); CoUninitialize(); return 0; }
NOW, here is THE PROBLEM. When I call "p(bstr)" I do get to "print_me()", BUT the parameter "txt" is not passed to the function correctly (I sends a whole different address, so it is a BAD POINTER). ANY IDEAS???? THANKS A LOT IN ADVANCE!I probably shouldn't encourage this sort of low level hackery, it'll only hurt someone you work with one day... However, why what you're up to won't work is due to the "this" pointer. All C++ member function calls have an implied first parameter which is the address of the object the function is invoked on. So if you write: a->b( c ); the compiler converts this to: ::b( &a, c ); So in your case if you call: p( &comobj, bstr ); it might all start working swimmingly. Oh, and if it does don't tell anyone I told you or generations of coders will be cursing my name for spreading low level hacks around. Cheers, Ash
-
I probably shouldn't encourage this sort of low level hackery, it'll only hurt someone you work with one day... However, why what you're up to won't work is due to the "this" pointer. All C++ member function calls have an implied first parameter which is the address of the object the function is invoked on. So if you write: a->b( c ); the compiler converts this to: ::b( &a, c ); So in your case if you call: p( &comobj, bstr ); it might all start working swimmingly. Oh, and if it does don't tell anyone I told you or generations of coders will be cursing my name for spreading low level hacks around. Cheers, Ash
Great answer. Including all of the "It wasn't me who told you how to do this". :)
Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
-
I probably shouldn't encourage this sort of low level hackery, it'll only hurt someone you work with one day... However, why what you're up to won't work is due to the "this" pointer. All C++ member function calls have an implied first parameter which is the address of the object the function is invoked on. So if you write: a->b( c ); the compiler converts this to: ::b( &a, c ); So in your case if you call: p( &comobj, bstr ); it might all start working swimmingly. Oh, and if it does don't tell anyone I told you or generations of coders will be cursing my name for spreading low level hacks around. Cheers, Ash
It works! :-) That's so awesome! I'm just asking to get the whole idea of that interface, COM and vtable stuff better. Thanks a lot ! :-)
-
It works! :-) That's so awesome! I'm just asking to get the whole idea of that interface, COM and vtable stuff better. Thanks a lot ! :-)