0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows DLL内の関数を呼び出す方法

Posted at

初めに

DLLの書き方

__declspec(dllexport)を書かないと外部からこの関数を呼び出せない。

mylib.c
#include <windows.h>

__declspec(dllexport) int add_numbers(int a, int b) {
    return a + b;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    return TRUE;
}

呼び出し部分

main.c全体
main.c
#include <windows.h>

typedef int (*AddFunc)(int, int);
int g_result = 0; // 計算結果を保持する広域変数

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            
            // 背景を塗りつぶし
            RECT rect;
            GetClientRect(hWnd, &rect);
            FillRect(hdc, &rect, GetSysColorBrush(COLOR_WINDOW));
            
            // 計算結果を表示
            char buf[100];
            sprintf(buf, "5 + 3 = %d", g_result);
            TextOut(hdc, 50, 50, buf, strlen(buf));
            
            EndPaint(hWnd, &ps);
            break;
        }
        
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
            
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow) {
    // DLLの読み込み
    HINSTANCE hDll = LoadLibrary("mylib.dll");
    if (!hDll) return 1;
    
    AddFunc add_numbers = (AddFunc)GetProcAddress(hDll, "add_numbers");
    if (!add_numbers) {
        FreeLibrary(hDll);
        return 1;
    }
    
    // 計算実行
    g_result = add_numbers(5, 3);
    
    // ウィンドウクラス登録
    WNDCLASS wc = {0};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszClassName = "MainWindow";
    
    if (!RegisterClass(&wc)) {
        FreeLibrary(hDll);
        return 1;
    }
    
    // ウィンドウ作成
    HWND hWnd = CreateWindow(
        "MainWindow",
        "DLL GUI Demo",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        400, 300,
        NULL, NULL, hInstance, NULL);
        
    if (!hWnd) {
        FreeLibrary(hDll);
        return 1;
    }
    
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    
    // メッセージループ
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    FreeLibrary(hDll);
    return (int)msg.wParam;
}
DLLの呼び出し部分.c
    // DLLの読み込み
    HINSTANCE hDll = LoadLibrary("mylib.dll");
    if (!hDll) return 1;

    //関数アドレス取得
    AddFunc add_numbers = (AddFunc)GetProcAddress(hDll, "add_numbers");
    if (!add_numbers) {// 関数取得に失敗
        FreeLibrary(hDll);//解放
        return 1;
    }
    
    // 計算実行
    g_result = add_numbers(5, 3);

動作確認

コンパイル方法

gcc -shared -o mylib.dll mylib.c
gcc -o main.exe main.c -lgdi32

動作

image.png
image.png

動作環境

windows7 Version6.1.7601
GCC-6.3.0-1

(帰省中につき一時的に昔のパソコンを使用している。windows7が懐かしい。。。)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?