Step by Step: Calling C DLLS from VC and VB
Step by step to call C DLL with VC and VB.
Author Hans Dietrich translation of soot
Introduction
This series of tutorials discussed four ways to use DLL in ordinary circumstances.
Part 1
Computing C DLL from VC Application
Class C DLL from VC Application
Part 2
Call the function of C DLL from the VB application
Part 3
Class C DLL from VB applications
Part 4
Call C DLL function from VC applications
Computing C DLL from VC Application
Visual Studio 6 makes it easy to create a dynamic connection library (DLL) that creates functions or classes.
first step
Open Visual Studio and select File | New Menu Item: Select Win32 Dynamic Link Library, enter Engineering Name, knock OK. Select A DLL That Exports some symbols and click Finish. You will see the following project files in File View:
Second step
In Test.cpp, you will see the following code:
// Test.cpp: Defines the entry point for the DLL application.//#include "stdafx.h" #include "Test.h" 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 variableTEST_API int nTest = 0; // This is an example of an exported function.TEST_API int fnTest (void ) {RETURN 42;} // this is the constructor of a class thing haas been exported.// See Test.h for the class definitioncte :: ctest () {return;}
Test.cpp
Contain
Fntest and Ctest :: Ctest
.
If you compile Test.dll now, you will get one can be used by others.
VC
The application is directly called
DLL.
Allow other
VC
Key mechanism for program calls
(Key Mechanism)
It is included in
Test.h
in
:
// 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 TEST_EXPORTS symbol defined on the command line.// This symbol should not be defined on any project that uses this DLL.// This way any other project whose source files include this file see // TEST_API functions as being imported from a DLL, whereas this DLL // sees symbols defined with this macro as being exported. # ifdef TEST_EXPORTS # define TEST_API __declspec (dllexport) # else # define TEST_API __declspec (dllimport) # endif // This class is exported from the Test.dllclass TEST_API CTest {public: CTest (void); // TODO: add your methods here.} Extern test_api int NTEST; TEST_API INT FNTEST (VOID); what happened here? #ifdef test_exports What does it mean? Test_exports is defined? Test_Exports If it is defined, Test_API will be defined as __Declspec (DLLEXPort) (DLL Export), otherwise it will be defined as __declspec (dllimport) (DLL import). This will affect the CTEST class defined behind is the dealer or import class. This means that if we need to export, we Before you define Test_Exports. When a VC application is accessible At this DLL, you can link the Test.lib link, which contains the export symbol of the DLL.
third step
Test_exports
Where is defined?
? DLL Wizard
Dry an incident
,
It
Test_exports
Put it in the command line
.
select
Project | Settings | C / C | General,
You will see the project options
:
Of course, this approach is feasible. But it is easy to negtegle, and it may lead to the trouble on maintenance. I prefer to clearly understand the definition test_Exports: remove / D "Test_exports from the project option, then in Test. CPP to define it: // Test.cpp: Defines the entry point for the dll Application.//include "stdafx.h" #define test_exports // <=== add this line # include "test.h" BOOL APIENTRY DLLMAIN (Handle HModule, DWORD UL_REASON_FOR_CALL, LPVOID LPRESERVED) {... Note #define test_exports before #include "test.h". So, it defines that you want to be in the header file. Now, you can recompile our previous Test.dll, we will get a DLL that can be called by other VC applications. Fourth step
How do we call the function in the DLL? For example, I created an example with VS. Choose the MFC AppWizard (EXE), enter the project name, then point OK. Select the dialog box. Point finish. Open xxxdlg.cpp XXX is your project name.) Find the OnInitDialog () member function, knock in the following code:
................................................ .. // set Small icon // code to test test.dll function: int n = fntest (); // <=== add this line // code to test; // <=== add this line return True; // return true unless}
the fifth step
We haven't written the code yet.
,
Now I have to put
Test.h
This one
DLL
The header file contains it:
// Testexedlg.cpp: importation file // # include "stdafx.h" #include "testexe.h" #include "test.h" #include "test.h" // <=== add this line ...
Sixth step
If you want to hurry to make a demonstration, you may try only to copy the DLL Test.h to your project directory, then the compiler will find it. But when the project is very big, this is not a good idea, Because when you update your DLL file, you may be in danger. For example, I forgot to copy it to your EXE directory. There is a simple method to solve this problem: Choose Project | Settings | C / C | Settings | Preprocessor, and add the Additional Include Directories: (Directory of the DLL Project) Tips This is actually assumed that the DLL project and the EXE project have the same project directory.
Now when I compiled, I got a Linker Errors !! DELETING Intermediate Files and Output Files for Project 'TESTEXE - WIN32 Debug' .------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Configuration: TESTEXE - WIN32 Debug --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Linking ... TestExeDlg.obj: error LNK2001: unresolved external symbol "__declspec (dllimport) public: __thiscall CTest :: CTest (void)" (__imp _ ?? 0CTest @@ QAE @ XZ) TestExeDlg.obj: error LNK2001: unresolved external symbol "__declspec (dllimport) int __cdecl fnTest (void)" (__imp_ fnTest @@ YAHXZ?) Debug / TestExe.exe: fatal error LNK1120: 2 unresolved externalsError executing link.exe.TestExe.exe - 3 error (s), 0 Warning (s)
Seventh step
Although I have already told the compiler DLL symbol, but the linker still doesn't know. So we must tell the linker .. Select Project | Settings | Link, add the DLL's lib file to Object / Library Modules: ------ ------------------------------------------
Eighth step
Ok, now compile. Before we run the program, don't forget one thing: copy Test.dll to the exe directory.
Ninth step
Next, you can put a breakpoint to the OnInitDialog () function, point Go (F5) debugging:
It can be seen that Fntest returns 42, as we predict. The CTest class can also be tested in a similar way.
Point.
The VS Engineering Wizard provides us with a good start to create a VC DLL.
Functions, classes, and variables can be exported from DLLs.
Using the #define preprocessor definition, a header file will be available in DLL and applications.
DLL exports its symbol, and the application imports this DLL symbol. When compiling the application, the compiler can see the DLL symbols seen by the header file, when the application is linked, the linker sees the DLL through the import library (Test.lib) symbol.
When an application is executed, the DLL must be placed in the same directory as EXE. DLL can also be placed in a Windows or System directory, which is also possible, but it often causes certain problems, so it should avoid this
Note:
In actual work, I rarely use the method in the seventh step. If this is done, in large projects, the DLL and LIB files will often become difficult to manage. We will think of building a lib directory and a bin Directory, put in all the lib files, DLL files, and exe files we have to use here. If this is done, how do we tell the linker to find a lib file? There are two ways to do: 1. Select Tools | Options | Directories and Set Show Directories for "library files". Add the path to the lib file used by our project below.
2. Another way is to select Project | Settings | Link, select category to input the path of the lib file used by the Used Library Path Basket below.
Which method is better? This depends on your development environment. The first method requires the entire project to share the set directory path, and all the VS required for all developers must be set to these paths.
The second method allows each project to customize its own path, and stored in the engineering, if the same directory is stored on the developer's computer, each developer can check out the project and design., This can be avoided The same path is set on each machine.
By now, I haven't said how to specify the lib file to use, my way is to add two lines in the DLL Test.h, now it looks like the next:
#ifdef TEST_EXPORTS #define TEST_API __declspec (dllexport) #else #define TEST_API __declspec (dllimport) #pragma message ( "automatic link to Test.lib") // <== add this line #pragma comment (lib, "Test.lib ") // <== add this line # Endif // this class is exported from the test.dllclass test_api ctest {public: ctest (void);}; extern test_api int ntest; test_api int wildst (void);
Doing so, it ensures that when the project contains the DLL header file, it will automatically put the DLL LIB link in, we can see the "Automatic Link to Test.lib" of #pragma message from the Output window of VS. This news. (PS: Original here http://www.codeproject.com/dll/xdllpt1.asp demo can also be downloaded here)