Explicit use of DLL export class _ using vtable

Source: Internet
Author: User
Tags export class

/// // Trydll2.h ///

// The following ifdef block is the standard way of creating macros which make exporting
// From a DLL simpler. All files within this DLL are compiled with the trydll2_exports
// Symbol defined on the command line. This symbol shocould not be defined on any project
// That uses this DLL. This way any other project whose source files include this file see
// Trydll2_api functions as being imported from a DLL, wheras This dll sees symbols
// Defined with this macro as being exported.
# 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; // it will not be redefined here !!

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; // will cause redefinition
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 ()
{
Return new ctrydll2;
}
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;
}

,,,,,,,,,,,,,,,,,,,,,,,,,,,,

// Usedll. cpp: defines the entry point for the console application.
//

# Include "stdafx. H"

# Include "../trydll2.h" // must be added because the class ctrydll2 is used.
// Use the commented-out code segment below if the file is not included
// Begin. Tell the compiler that these things will be poured out from the outside. This part includes the header file...
/*
Class _ declspec (dllimport) ctrydll2
{
Public:
Ctrydll2 (void );
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;
}
// Fntrydll2: do not forget that the C ++ default compiler will rename the function.
// So you should force a statement not to be renamed
// However, It is troublesome to reload .. Because reload is the method for renaming an application.
// ...... 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;
}
// Ntrydll2 = 100; // The name cannot be changed even if the DLL is declared as extern "C ".
// Attempts to link, so the Link always fails. If the _ declspec (dllimport) int ntrydll2 at the top is not found;
// Compilation fails at all
// ............... Class ........
Ctrydll2 * PT = NULL;
Farproc lpfn2 =: getprocaddress (HI, "getinstance ");
If (lpfn2 = NULL)
{
Cout <"getprocaddress getinstance error/N ";
Return 0;
}
PT = (ctrydll2 *) lpfn2 ();
Pt-> diplay (); // an error occurs during connection. In essence, what is exported using DLL is displayed, so that this cannot be linked.
Pt-> FNP (10 );
// Vtable, but it will not be linked during the link.
// Fntrydll2 ();
/*
How can I use the exported class or variable ??
*/
: Freelibrary (HI );
Return 0;
}
,,

, Please take a look at the above Code comments

Here is a note: the class that can be explicitly exported using DLL is because of the existence of vtable !! This is the decisive factor. Global variables used as comparison expressions cannot be used. Because an error occurs during the link. Vtable is determined during running, so the Connection check is avoided.

Now, let's think about why vitual FN is the best interface in C ++. I want to have something to do with it. This should start with COM. In essence, C ++ does not have the interface concept but can exist. The vtable attribute of the interface is used in COM to avoid the check during the connection and directly determine the runtime.

Haha.

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.