Calling a function in a DLL in C + + (3)

Source: Internet
Author: User

Transferred from: http://www.cnblogs.com/woshitianma/p/3681745.html

Advantages of 1.dll

Code reuse is an important way to improve the efficiency of software development. In general, as long as a part of the code is generic, it can be constructed as a relatively independent function module and reused in subsequent projects. A more common example is the various application frameworks, ATL, MFC, and so on, which are published as source code. Since this reuse is "source level", the source code is completely exposed to the programmer, so called "white box Reuse".  "White box reuse" of the shortcomings are more, summed up there are 4 points. Exposing the source code, multiple copies, resulting in storage waste, easily with the programmer's "normal" code naming conflict, updating the function module is difficult, is not conducive to the modular implementation of the problem; in fact, the above 4 points are summed up as "exposed source code" resulting in "severely coupled codes." To compensate for these shortcomings, a "binary level" code reuse is proposed. The use of binary-level code reuse to some extent hides the source code, to alleviate the code coupling phenomenon played a role. This reuse is referred to as "black box multiplexing".

Description: The way to implement "black box multiplexing" is not only a DLL, but also a static link library and even more advanced COM components.

Creation of 2.dll

Reference Program Original: http://msdn.microsoft.com/zh-cn/library/ms235636.aspx

New "Win32 Project", select the application Type "DLL", other default. Add header file Testdll.h

Testdll.h

#ifdef testdll_exports #define TESTDLL_API __declspec (dllexport) #else #define TESTDLL_API __declspec (dllimport)       #endif namespace Mathfuncs {//This class was exported from the Testdll.dll class Mymathfuncs { Public://Returns A + b static Testdll_api double Add (double A, double b);
Returns A-B static Testdll_api double Subtract (double A, double);
Returns A * b static TESTDLL_API double Multiply (double A, double b);
Returns A/b//Throws const std::invalid_argument& If B is 0 static TESTDLL_API double Divide     (Double A, double b);   }; }

When the symbol TESTDLL_EXPORTS,TESTDLL_API is defined is set to the __declspec (dllexport) modifier, this modifier enables the function to being exported by the DLL so-it can be used by other applications. If undefined then Testdll_api is set to __declspec (dllimport), this modifier enables the compiler to optimize the importing of the function fro The M the DLL for use in other applications. When a DLL project is built, Testdll_exports is defined by default, so the __declspec (dllexport) modifier is set by default.

Add CPP File

Testdll.cpp: Defines an export function for a DLL application.

#include "stdafx.h" #include "testdll.h" #include <stdexcept> using namespace std;
Namespace Mathfuncs {Double Mymathfuncs::add (double A, double b) {return a + B; }
Double Mymathfuncs::subtract (double A, double b) {return a A; }
Double mymathfuncs::multiply (double A, double b) {return a * b; }
Double Mymathfuncs::D ivide (Double A, double b) {if (b = = 0) {throw Invalid_argum           ENT ("B cannot be zero!");       } return a/b; }   }

The compilation generates the corresponding DLL file, and the corresponding LIB file is generated.

Note: A. There are two ways to declare an exported function in a DLL: Add __declspec (dllexport) to the function declaration, and use a module definition (. def) file declaration.  See: http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792099.html B. Using the extern "C" flag when creating a DLL for C files or when you want to use the C compiler, see simple parsing of extern "C" (calling a function in a DLL in C + + (1))

3.dll of Calls

An application can use DLLs in two ways: one is implicit (called) and the other is an explicit link. Before using a DLL, you first need to know the structure information of the function in the DLL. VS has a small program named Dumpbin.exe in the VC\bin directory that allows you to view the structure of a function in a DLL file. A comparison of the two is detailed in: http://blog.sina.com.cn/s/blog_53004b4901009h3b.html

The implicit link adopts static loading, which is simpler and requires. h,. lib,. dll three-piece set. The new console application or empty project configuration is as follows : (Very critical)

Configuration Properties---Properties---->vc++ Directory Add header file testdll.h directory in "Include directory"

Configuration Properties---Properties--->vc++ directory, add header file Testdll.lib directory in the library directory

Add "Testdll.lib" in "Additional Dependencies" (if more than one Lib is separated by a space), type------------configuration Properties------

Add CPP File

Mydll.cpp

#include <iostream> #include "testdll.h" using namespace std;
int main () {Double A = 7.4; int b = 99;
cout << "A + b =" << Mathfuncs::mymathfuncs::add (A, b) << Endl;       cout << "A-B =" << mathfuncs::mymathfuncs::subtract (A, c) << Endl;       cout << "A * b =" << mathfuncs::mymathfuncs::multiply (A, b) << Endl; cout << "A/b =" << Mathfuncs::mymathfuncs::D ivide (A, b) << Endl;
    try       {            cout <<  "a / 0 = "  <<                mathfuncs::mymathfuncs::D ivide (a, 0)   << endl;        }       catch  ( const invalid_argument &e)         {            cout <<  "caught exception: "  <<  E.what ()  << endl;        }        return 0;  } 

It is now possible to compile, but the program runs with an error, and you need to copy the Testdll.dll to the same directory as the executable file that the current project generates .  Explicit linking is an application that can load DLL files at any time during execution, or can unload DLL files at any time, which is not possible with implicit links, so explicit links are more flexible and more appropriate for explanatory languages. New project, no special configuration required, add CPP file

#include <Windows.h>//Loaded header files

#include <iostream> using namespace std;
Int main ()    {       typedef double  (*padd) (double a ,  double b);     typedef double  (*psubtract) (DOUBLE&NBSP;A,&NBSP;DOUBLE&NBSP;B);       hmodule hdll = loadlibrary ("Testdll.dll")  //Load DLL file       if (hdll != null)        {            padd fp1 = padd (GetProcAddress (hdll,  Makeintresource (1)));  //gets the first function in the DLL         if (fp1 !=  NULL)            {         &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;COUT&LT;&LT;FP1 (2.5, 5.5) <<endl;           }           else            {                cout<< "cannot find function " << "Add" <<endl;           }            Psubtract fp2 = psubtract (GetProcAddress (hdll,  "[email protected]@[email  Protected]@[email protected]);  //get the function labeled "?..." in the DLL, the C + + compiler considers the parameters of the function          if (fp2 != null)            {    &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;COUT&LT;&LT;FP2 (5.5, 2.5) <<endl;           }            else           {                cout<< "cannot find function " << " Subtract "<<endl;           }            freelibrary (hdll);       }        else       {            std::cout<< "cannot find " << "Testdll" <<std::endl;        }       return 1;  } 

Explicitly called problem: in the DLL file, the function name in the DLL project changes (c + + compiler) in the process of compiling the DLL, and the character in the DLL file is said to be "name marked". The second parameter in GetProcAddress can be obtained by the order of the functions in the DLL file, or directly using the "name label" in the DLL file, which can be viewed through the Dumpbin.exe applet. If the C + + compiler wants to make the function name more canonical (as in the original project), see: http://blog.csdn.net/btwsmile/article/details/6676802.

Of course, the most common way to make the function name more canonical is to use the C compiler to compile the function during DLL creation so that the function name in the DLL file is consistent with the function name in the original DLL project.

4. More general Explicit invocation

To solve the last problem, you can use extern "C" to establish a C connection for a function in a DLL project, and a simple example works as follows. In a project created by the DLL, add the CPP file

#include "stdafx.h"

#ifdef __cplusplus//If used by C + + code extern "C" {//We need to export the C interface #endi F
__declspec (dllexport) int addfun (int a, int b) {return a+b;}
#ifdef __cplusplus} #endif compile to generate DLL files. In DLL call project, add CPP File/* * Houkai * Description: Explicitly call DLL * Date: 2013-6-5 */#include <windows.h> #include <iostream> using names Pace std;
Void main () {    typedef int (*funa) (int,int);     hmodule  hmod = loadlibrary ("Cdll.dll");//dll path     if  (hmod)      {        FUNA addfun =  (Funa) GetProcAddress (Hmod,  text ("Addfun"));//Direct use of the original engineering function name           if  (addfun ! = null)         {             cout<<addfun (5, 4) <<endl;         }         else          {             cout<< "Error on getprocaddress" <<endl;         }        &nBsp FreeLibrary (HMOD);     }     else         cout< < "Error on loadlibrary" <<endl; } 

Run so that you can call the DLL's function. Further, if the above DLL file is invoked by an implicit invocation, the calling function should be called by the. dll,. lib file.

Implicit links

#include <iostream> #pragma comment (lib, "Cdll.lib") using namespace std;
extern "C" _declspec (dllimport) int addfun (int a,int b); Loaded with the Addfun function, where the. h file is used to function in the//dll C compiler is required here extern "C" if the DLL is not extern "C"//Here is: _declspec (dllimport) int addfun (int A, int b); void Main () {Cout<<addfun (5,4) <<endl;}

Calling a function in a DLL in C + + (3)

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.