|
The virtual table is in the order that virtual functions are defined. (I think...)
where the slot 0 contains run-time type class id, slot 1 contains pointer to the first virtual function, slot 2 contains pointer to the second virtual function etc.
|
|
|
|
|
If that option is enabled. I don't ever use it.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
|
The binary layout of a C++ object is a structure which keeps the attributes ( in the order of definition ) and if the class inherits from some other classes the structure is prefixed with the parent vptr table and data ( in the order of definition). So, for a simple hierarchy like "class child : public parent " the layout will be:
parent::vptr_table
parent::data
child::data
and if we have a more complex hierarchy like :
class base;
class parent1 : public virtual base;
class parent2 : public virtual base;
class child : public parent1, public parent2
the layout will be:
base::vptr_table
base::data
parent1::vptr_table
parent1:data
parent2:vptr_table
parent2::data
child::data
Let’s say you have a class named CObject and you create an instance called x . Since the calling convention of a member function is the "this" convention , the compiler will just copy into the ECX register the "this" value for x object , will push the parameters on the stack and will call the method :
Lea ecx, x
Push ..
Call CObject::method
If you will define another instance of CObject called y the method call will be :
Lea ecx, y
Push ..
Call CObject::method
If you want to access the attributes just point to the class location and get the variable by offset, and to call method functions thru vptr table all you have to do is pointer arithmetic . If you have time you can check this sample :
#include <stdio.h>
class CBase1
{
public:
virtual void b1_test1() = 0;
virtual void b1_test2() = 0;
};
class CBase2
{
public:
virtual void b2_test1() = 0;
virtual void b2_test2()
{
};
virtual void b2_test3()
{
};
};
class CTest : public CBase1, public CBase2
{
public:
void b1_test1();
void b1_test2();
void b2_test1();
void b2_test3();
void b2_test2()
{
printf("b2_test2\n");
};
};
void CTest::b1_test1()
{
printf("b1_test1\n");
};
void CTest::b1_test2()
{
printf("b1_test2\n");
};
void CTest::b2_test1()
{
printf("b2_test1\n");
};
void CTest::b2_test3()
{
printf("b2_test3\n");
};
void test_vptr()
{
CTest x;
//call CBase1::b1_test1
_asm
{
lea ecx, x
mov eax, dword ptr[ ecx] //get CBase1 vptr
call dword ptr[ eax + 0] //first method from table
}
//call CBase2::b2_test3
_asm
{
lea ecx, x
mov eax, dword ptr[ ecx + 4] //get CBase2 vptr - second base class
call dword ptr[ eax + 8] //third method from table
}
//call CBase2::b2_test2
_asm
{
lea ecx, x
mov eax, dword ptr[ ecx + 4] //get CBase2 vptr
call dword ptr[ eax + 4] //second method from table
}
};
class CSimple
{
private:
int k;
int f;
public:
CSimple(int v)
{
k = v;
f = 3;
}
void test();
};
void CSimple::test()
{
printf("simple::test\n");
};
void test_simple()
{
CSimple x(1);
CSimple y(2);
int t = 0;
//printf x.k
_asm
{
mov eax, dword ptr[ x]
mov t, eax
}
printf("x::k : %d\n", t);
//printf x.f
_asm
{
mov eax, dword ptr[ x + 4]
mov t, eax
}
printf("x::f : %d\n", t);
//printf y.k
_asm
{
mov eax, dword ptr[ y]
mov t, eax
}
printf("y::k : %d\n", t);
}
void main(void)
{
test_vptr();
test_simple();
}
|
|
|
|
|
Thanxs to everybody for this bunch of replies. I'm going to have a fun time digesting them Regards
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I hope it didn't make you ill
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Is it possible to create an array of objects or an array of pointers to objects. I think the later is what I am really after.
I have tried doing such a beast and all I get is an error.
class Bar
{
Bar(CString strName, CString strAddress)
}
class Foo
{
protected:
Bar* m_poBars[16];
public:
Foo();
Create(INT nIndex);
}
Foo::Foo()
{
for (INT i; i < 16; i++)
{
m_poBars[i] = NULL;
}
}
Foo::Create(INT nIndex)
{
m_poBars[nIndex] = new Bar("My Place", "123 Road");
}
The above code doesn't seem to be too happy and I was wondering what I am doing wrong.
Cheers,
Clint Singer
|
|
|
|
|
I think everything is perfect except the following line:
for (INT i; i < 16; i++)
You forgot to initialize i :
for (INT i=0; i < 16; i++)
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I can't believe it. The INT i... Well it was the problem. I made the mistake in my posting and in my code. What is worse, the posting was totally made up to simplify the problem. I don't know how many times I looked at my real code and didn't notice that I wasn't initalizing i to Zero. Boy, I feel silly
Cheers,
Clint Singer
|
|
|
|
|
Didn't you get a warning? The compiled should have issued one on this.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Like Joaquin said it looks good except for the initialazation part of 'i'. However, if that does not resolve your problem what is the specific error message you are getting? That would help diagnose the problem.
PLUS are you sure that is where the error is generated? Your example class BAR is defined such as:
class Bar
{
Bar(int strName, int strAddress);
};
The problem with this is that Bar is now a private Constructor by default. You would have problems initializing this in your main function when it calls FOO create unless this is declared as a friend of the class, but that wasn't appearent in your example. Plus you may want to add to the end of your constructor { } so it would be an inline function or define it somewhere else or you may get a linker error.
Hope this helps out...I don't even know what I'm talking about right now...need more coffee
HomeNuke
----
"Nuke'd Your Home, Yet?"
Run your own PostNuke based web server from home
http://www.homenuke.com
|
|
|
|
|
Some mistakes on my part. The Bar() constructor is infact public: and INT i is indeed INT i = 0; They are just wrong on my posting, sorry. I am still getting the error. To add more to the story I am making a simple ActiveX control and running it in visual basic. The errors I get are as such when I try to do m_poBars[i] = NULL;
First-chance exception in VB6.EXE (DVMS CLIENT LIB.DLL): 0xC0000005: Access Violation.
First-chance exception in VB6.EXE (KERNEL32.DLL): 0x80010105: (no name).
|
|
|
|
|
So the error you are getting is from the client side? Oh OK I'm thinking from a straight C++ side application Let me review this some more...sorry for not understanding the question in the first place.
HomeNuke
----
"Nuke'd Your Home, Yet?"
Run your own PostNuke based web server from home
http://www.homenuke.com
|
|
|
|
|
I'd try to reproduce the error in a VC++-only application, without all the ActiveX mess.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I tried it with a MFC exe dialog and it seems to work just as I had expected it too. I guess I will have to do some more trial and error to find the problem.
Cheers,
Clint Singer
|
|
|
|
|
If you're runnign in ActiveX from VB, then how do you know what line is causing the problem????
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
And you should probably check that your arg to the create function is in bounds.
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
How to minimaze a dialog ?
|
|
|
|
|
You need to add the minimize box in the Resource Editor...
Then you must to use CWnd::SetWindowPlacement...
Best Regards
Carlos Antollini.
Sonork ID 100.10529 cantollini
|
|
|
|
|
First Dialog Must Support Minimize Button..
and this will do it.
AfxGetApp()->m_pMainWnd->ShowWindow(SW_MINIMIZE);
Rememder m_pMainWnd is the Main Window..
or
this->ShowWindow(SW_MINIMIZE);
Gaurika Wijeratne..
www.gaurika.com/ gaurika@sltnet.lk
|
|
|
|
|
I am trying to find out a value from a specific column and row from a MSFlexGrid. I set the text by calling:
m_flxCompanyList.SetTextArray(GridPos(i,1),pComp->m_strRetailNum);
m_flxCompanyList.SetTextArray(GridPos(i,2),pComp->m_strCompName);
so I construct a two column list of companies and their retail numbers, what I want to do is make it so that when someone clicks on the grid i can get the value in the first column of whatever row they select.
I know how to get what position is selected, but the GetTextArray (which I would think goes along with SetTextArray) returns a long, and I can't figure out what to do with it!
I've searched msdn and these message boards and it seems not much documentation is available for this control, but im hoping someone can help out?
thanks in advance to any advice
-dz
|
|
|
|
|
I don't know a lot about MSFlexGrid, but try CString = GetTextMatrix(row,col)
|
|
|
|
|
just what i needed, thank you SOOO much!
-dz
|
|
|
|
|
I'm trying to integrate a PowerBuilder application with another application and I need to read some data from a PowerBuilder screen. It appears to be a standard dialog/view, but if you try to examine the individual controls, they are part of some custom "panel". Has anyone done anything similar to what I am trying to do and has some advice?
Thanks,
David
|
|
|
|
|
Maybe Spy++ (one of the utilities that come with Visual Studio) can help you get an idea of how those PowerBuilder windows are made up.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|