操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊


    indows 應用程序入口函數

    GUI(Graphical User Interface)應用,鏈接器選項:/SUBSYSTEM:WINDOWS

    CUI(Console User Interface)應用,鏈接器選項:/SUBSYSTEM:CONSOLE

    _tWinMain 與 _tmain 函數聲明

    Int WINAPI _tWinMain(
        HINSTANCE hInstanceExe,
        HINSTANCE,
        PTSTR pszCmdLine,
        int nCmdShow);
    
    int _tmain(
        int argc,
        TCHAR *argv[],
        TCHAR *envp[]);

    Windows 的動態鏈接庫(Dynamic-Link Library)

    部分知識點來自《Windows 核心編程(第五版)》

    用處

    (1)擴展了應用程序的特性

    (2)簡化了項目管理

    (3)有助于節省內存

    (4)促進了資源的共享

    (5)促進了本地化

    (6)有助于解決平臺間的差異

    (7)可以用于特殊目的

    注意

    (1)創建 DLL,事實上是在創建可供一個可執行模塊調用的函數

    (2)當一個模塊提供一個內存分配函數(malloc、new)的時候,它必須同時提供另一個內存釋放函數(free、delete)

    (3)在使用 C 和 C++ 混編的時候,要使用 extern "C" 修飾符

    (4)一個 DLL 可以導出函數、變量(避免導出)、C++ 類(導出導入需要同編譯器,否則避免導出)

    (5)DLL 模塊:cpp 文件中的 __declspec(dllexport) 寫在 include 頭文件之前

    (6)調用 DLL 的可執行模塊:cpp 文件的 __declspec(dllimport) 之前不應該定義 MYLIBAPI

    加載 Windows 程序的搜索順序

    1、包含可執行文件的目錄

    2、Windows 的系統目錄,可以通過 GetSystemDirectory 得到

    3、16 位的系統目錄,即 Windows 目錄中的 System 子目錄

    4、Windows 目錄,可以通過 GetWindowsDirectory 得到

    5、進程的當前目錄

    6、PATH 環境變量中所列出的目錄

    DLL 入口函數

    DllMain 函數

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch(fdwReason)
        {
        case DLL_PROCESS_ATTACH:
            // 第一次將一個DLL映射到進程地址空間時調用
            // The DLL is being mapped into the process' address space.
            break;
        case DLL_THREAD_ATTACH:
            // 當進程創建一個線程的時候,用于告訴DLL執行與線程相關的初始化(非主線程執行)
            // A thread is bing created.
            break;
        case DLL_THREAD_DETACH:
            // 系統調用 ExitThread 線程退出前,即將終止的線程通過告訴DLL執行與線程相關的清理
            // A thread is exiting cleanly.
            break;
        case DLL_PROCESS_DETACH:
            // 將一個DLL從進程的地址空間時調用
            // The DLL is being unmapped from the process' address space.
            break;
        }
        return (TRUE); // Used only for DLL_PROCESS_ATTACH
    }

    載入卸載庫

    LoadLibrary、LoadLibraryExA、LoadPackagedLibrary、FreeLibrary、FreeLibraryAndExitThread 函數聲明

    // 載入庫
    HMODULE WINAPI LoadLibrary(
      _In_ LPCTSTR lpFileName
    );
    HMODULE LoadLibraryExA(
      LPCSTR lpLibFileName,
      HANDLE hFile,
      DWORD  dwFlags
    );
    // 若要在通用 Windows 平臺(UWP)應用中加載 Win32 DLL,需要調用 LoadPackagedLibrary,而不是 LoadLibrary 或 LoadLibraryEx
    HMODULE LoadPackagedLibrary(
      LPCWSTR lpwLibFileName,
      DWORD   Reserved
    );
    
    // 卸載庫
    BOOL WINAPI FreeLibrary(
      _In_ HMODULE hModule
    );
    // 卸載庫和退出線程
    VOID WINAPI FreeLibraryAndExitThread(
      _In_ HMODULE hModule,
      _In_ DWORD   dwExitCode
    );

    顯示地鏈接到導出符號

    GetProcAddress 函數聲明

    FARPROC GetProcAddress(
      HMODULE hInstDll,
      PCSTR pszSymbolName  // 只能接受 ANSI 字符串,不能是 Unicode
    );

    DumpBin.exe 查看 DLL 信息

    在 VS 的開發人員命令提示符 使用 DumpBin.exe 可查看 DLL 庫的導出段(導出的變量、函數、類名的符號)、相對虛擬地址(RVA,relative virtual address)。如:

    LoadLibrary 與 FreeLibrary 流程圖

    LoadLibrary 與 FreeLibrary 流程圖

    LoadLibrary

    FreeLibrary

    DLL 庫的編寫(導出一個 DLL 模塊)

    DLL 庫的編寫(導出一個 DLL 模塊) DLL 頭文件

    // MyLib.h
    
    #ifdef MYLIBAPI
    
    // MYLIBAPI 應該在全部 DLL 源文件的 include "Mylib.h" 之前被定義
    // 全部函數/變量正在被導出
    
    #else
    
    // 這個頭文件被一個exe源代碼模塊包含,意味著全部函數/變量被導入
    #define MYLIBAPI extern "C" __declspec(dllimport)
    
    #endif
    
    // 這里定義任何的數據結構和符號
    
    // 定義導出的變量(避免導出變量)
    MYLIBAPI int g_nResult;
    
    // 定義導出函數原型
    MYLIBAPI int Add(int nLeft, int nRight);

    DLL 源文件

    // MyLibFile1.cpp
    
    // 包含標準Windows和C運行時頭文件
    #include <windows.h>
    
    // DLL源碼文件導出的函數和變量
    #define MYLIBAPI extern "C" __declspec(dllexport)
    
    // 包含導出的數據結構、符號、函數、變量
    #include "MyLib.h"
    
    // 將此DLL源代碼文件的代碼放在此處
    int g_nResult;
    
    int Add(int nLeft, int nRight)
    {
        g_nResult = nLeft + nRight;
        return g_nResult;
    }

    DLL 庫的使用(運行時動態鏈接 DLL)

    DLL 庫的使用(運行時動態鏈接 DLL)

    // A simple program that uses LoadLibrary and 
    // GetProcAddress to access myPuts from Myputs.dll. 
     
    #include <windows.h> 
    #include <stdio.h> 
     
    typedef int (__cdecl *MYPROC)(LPWSTR); 
     
    int main( void ) 
    { 
        HINSTANCE hinstLib; 
        MYPROC ProcAdd; 
        BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 
     
        // Get a handle to the DLL module.
     
        hinstLib = LoadLibrary(TEXT("MyPuts.dll")); 
     
        // If the handle is valid, try to get the function address.
     
        if (hinstLib != NULL) 
        { 
            ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts"); 
     
            // If the function address is valid, call the function.
     
            if (NULL != ProcAdd) 
            {
                fRunTimeLinkSuccess = TRUE;
                (ProcAdd) (L"Message sent to the DLL function\n"); 
            }
            // Free the DLL module.
     
            fFreeResult = FreeLibrary(hinstLib); 
        } 
    
        // If unable to call the DLL function, use an alternative.
        if (! fRunTimeLinkSuccess) 
            printf("Message printed from executable\n"); 
    
        return 0;
    }

    運行庫(Runtime Library)

    典型程序運行步驟

    (1)操作系統創建進程,把控制權交給程序的入口(往往是運行庫中的某個入口函數)

    (2)入口函數對運行庫和程序運行環境進行初始化(包括堆、I/O、線程、全局變量構造等等)。

    (3)入口函數初始化后,調用 main 函數,正式開始執行程序主體部分。

    (4)main 函數執行完畢后,返回到入口函數進行清理工作(包括全局變量析構、堆銷毀、關閉I/O等),然后進行系統調用結束進程。

    一個程序的 I/O 指代程序與外界的交互,包括文件、管程、網絡、命令行、信號等。更廣義地講,I/O 指代操作系統理解為 “文件” 的事物。

    glibc 入口

    _start -> __libc_start_main -> exit -> _exit

    其中 main(argc, argv, __environ) 函數在 __libc_start_main 里執行。

    MSVC CRT 入口

    int mainCRTStartup(void)

    執行如下操作:

    (1)初始化和 OS 版本有關的全局變量。

    (2)初始化堆。

    (3)初始化 I/O。

    (4)獲取命令行參數和環境變量。

    (5)初始化 C 庫的一些數據。

    (6)調用 main 并記錄返回值。

    (7)檢查錯誤并將 main 的返回值返回。

    C 語言運行庫(CRT)

    大致包含如下功能:

    啟動與退出:包括入口函數及入口函數所依賴的其他函數等。

    標準函數:有 C 語言標準規定的C語言標準庫所擁有的函數實現。

    I/O:I/O 功能的封裝和實現。

    堆:堆的封裝和實現。

    語言實現:語言中一些特殊功能的實現。

    調試:實現調試功能的代碼。

    C語言標準庫(ANSI C)

    包含:

    標準輸入輸出(stdio.h)

    文件操作(stdio.h)

    字符操作(ctype.h)

    字符串操作(string.h)

    數學函數(math.h)

    資源管理(stdlib.h)

    格式轉換(stdlib.h)

    時間/日期(time.h)

    斷言(assert.h)

    各種類型上的常數(limits.h & float.h)

    變長參數(stdarg.h)

    非局部跳轉(setjmp.h)


    今天的分享就到這里了,大家要好好學C++喲~

    寫在最后:對于準備學習C/C++編程的小伙伴,如果你想更好的提升你的編程核心能力(內功)不妨從現在開始!

    編程學習書籍分享:

    編程學習視頻分享:

    整理分享(多年學習的源碼、項目實戰視頻、項目筆記,基礎入門教程)

    歡迎轉行和學習編程的伙伴,利用更多的資料學習成長比自己琢磨更快哦!

    對于C/C++感興趣可以關注小編在后臺私信我:【編程交流】一起來學習哦!可以領取一些C/C++的項目學習視頻資料哦!已經設置好了關鍵詞自動回復,自動領取就好了!

    使用GCC生成dll文件

    為什么要使用MingW呢?其實主要還是使用GCC,在Windows下主要有Mingw和Cywin,這里使用Mingw,因為GCC在生成動態庫,依賴項比較少,不像在VS生成依賴特定VC庫版本.在某些沒有VC庫對應的版本時是無法執行的.

    這篇文章是17年寫,是因為當時項目要調用C/C++生成動態庫(dll),因為當時一個同事是使用VS2015開發的,導致在現場的老機器無法直接使用.

    VS2008生成dll

    這里是生成c語言的動態庫,主要是為了讓c#調用.先來一段測試代碼.

    //vs編譯的話,要將函數導出
    _declspec(dllexport) int _stdcall add(int a, int b)  
    {
    	return a + b;
    }

    VS2008生成dll

    看一下VS2008生成dll,依賴的dll文件(VS生成dll,依賴具體某個版本vcruntime)

    vs2008生成dll文件依賴項,分別依賴msvcr90d.dll和kernel32.dll

    GCC生成

    不得不說,原先沒用過GCC生成dll,便在百度上進行搜索,發現全是肯定.代碼還是和用VC有區別,用GCC不需要對函數進行導出.

    代碼如下:

    int add(int a, int b)
    {
    	return a + b;
    }
    //注意編譯,只需要指定為*.dll 加上-shared
    gcc -o callback.dll  -shared main.c

    GCC生成dll,依賴kernel32.dll和msvrt.dll

    C#如何調用

    [DllImport("callback.dll", SetLastError = true)]
    static extern int add(int a, int b);
    
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            string txt1 = textBox1.Text;
            string txt2 = textBox2.Text;
            int sum = add(Convert.ToInt32(txt1), Convert.ToInt32(txt2)); //調用c語言生成動態庫中的方法
            textBox3.Text = sum.ToString();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.StackTrace);
        }
    }

    效果:

    C#調用C語言生成的動態庫

    個人能力有限,如果您發現有什么不對,請私信我

    如果您覺得對您有用的話,可以點個贊或者加個關注,歡迎大家一起進行技術交流

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有