Impact of dll_5 vtable layout on explicit DLL export classes

Source: Internet
Author: User

According to my test on VC, the conclusions are as follows:

The layout of vatabled by VC is determined as follows:

// This class is exported from the trydll2.dll
Class _ declspec (dllexport) ctrydll2 {
Public:
Ctrydll2 (void );
Virtual void diplay ();
Virtual int FNP (int I );
// Todo: add your methods here.
};

The vtbale layout is as follows:

Display () // the zeroth Element

FNP (INT) // The first element

,.. That is to say, they are determined in the order of the Declaration in vatable.

If you want to use it correctly on the client, you need to make sure that it is consistent !!!

Here is my error code:

///////////////

# Ifdef trydll2_exports
# Define trydll2_api _ declspec (dllexport)
# Else
# Define trydll2_api _ declspec (dllimport)
# Endif

// This class is exported from the trydll2.dll
Class trydll2_api ctrydll2 {
Public:
Ctrydll2 (void );
Virtual void diplay ();
Virtual int FNP (int I );
// Todo: add your methods here.
};

// Extern trydll2_api int ntrydll2; // · ~~ú~â à ²» áöø ~¨ ¨ å !!

Extern "C"
{
Trydll2_api int ntrydll2;
Trydll2_api ctrydll2 * getinstance ();
Trydll2_api int fntrydll2 (void );
Trydll2_api int FNP (INT para );
};
, Trydll2.cpp ,,,,,,,,,

# Include "stdafx. H"
# Include "trydll2.h"
//..............................
# Include <iostream>
Using namespace STD;
///..............................

Bool apientry dllmain (handle hmodule,
DWORD ul_reason_for_call,
Lpvoid lpreserved
)
{
Switch (ul_reason_for_call)
{
Case dll_process_attach:
Case dll_thread_attach:
Case dll_thread_detach:
Case dll_process_detach:
Break;
}
Return true;
}

// This is an example of an exported variable
// Trydll2_api int ntrydll2 = 0; // define «μ ö ööø ¨ å
Extern "C" trydll2_api int ntrydll2 = 0;

// This is an example of an exported function.
Trydll2_api int fntrydll2 (void)
{
Cout <"fntrydll2/N ";
Return 42;
}

Trydll2_api ctrydll2 * getinstance ()
{
Ctrydll2 * P = new ctrydll2;
Return P;
}
Trydll2_api int FNP (INT para)
{
Cout <"FNP:" <para <Endl;
Return para = 1;
}
// This is the constructor of a class that has been exported.
// See trydll2.h for the class definition
Ctrydll2: ctrydll2 ()
{
Return;
}

Void ctrydll2: diplay ()
{
Cout <"ctrydll2: diplay" <Endl;
}

Int ctrydll2: FNP (int I)
{
Cout <"ctrydll2: FNP:" <I <Endl;
I ++;
Return I;
}

, And client ............

# Include "stdafx. H"
 
Class _ declspec (dllimport) ctrydll2
{
Public:
Ctrydll2 (void );
Virtual int FNP (int I); // The Declaration Order here is different from that of DLL.
Virtual void diplay ();
// Virtual int FNP (int I );
// Todo: add your methods here.
};

// _ Declspec (dllimport) int ntrydll2;
// End £;£;£;£ ..
# Include "windows. H"
# Include <iostream>
Using namespace STD;

Int main (INT argc, char * argv [])
{
Hinstance HI =: loadlibrary ("E: // lianxi // dll_lib_dcom_com // trydll2 // debug // trydll2.dll ");
If (HI = NULL)
{
Cout <"loadlibrary error/N ";
Return 0;
}
// ...... FN .................
Farproc lpfn =: getprocaddress (HI, "fntrydll2 ");
If (lpfn = NULL)
{
Cout <"getprocaddress fntrydll2 error/N ";
Return 0;
}
Lpfn ();
// Farproc = int (* lpfn) (void)
Typedef int (* lpfnp) (INT );
Lpfnp = (lpfnp): getprocaddress (HI, "FNP ");
If (lpfnp = NULL)
{
Cout <"getprocaddress FNP error/N ";
}
Else
{
Lpfnp (15 );
}
// ...... Variable ................
Int * Pi = (int *): getprocaddress (HI, "ntrydll2 ");
If (Pi = NULL)
{
Cout <"cann't find ntrydll2 error/N ";
// Return 0;
}
// ............... Class ........
Ctrydll2 * PT = NULL;
Farproc lpfn2 =: getprocaddress (HI, "getinstance ");
If (lpfn2 = NULL)
{
Cout <"getprocaddress getinstance error/N ";
Return 0;
}

// Note: the compilation link is correct.
PT = (ctrydll2 *) lpfn2 ();
Pt-> diplay (); // during execution, FNP (INT) in DLL is actually called. However, the runtime error occurs because the parameter is incorrect.
Pt-> FNP (10); // during execution, display () in DLL is actually called. However, a runtime error occurs due to incorrect parameters.
/* The above error occurs because the vtable determined by main is different from the vatble of DLL. Which of the following statements is used to compile Main?

The vtable declared in main, but the PT points to the DLL vtable at runtime, so the call error occurs.

*/
: Freelibrary (HI );
Return 0;
}
// About this...

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.