2011-08-14 5 views
3

私は後でSetWindowsHookEx()関数を使っていくつかのプロセスに注入したいDLLをビルドしようとしています。奇妙なことは、DLLをロードしようとしたときにGetProcAddressを使用してその中に含まれるプロシージャのアドレスを取得しようとすると、CBTメッセージ処理プロシージャのアドレスを取得しようとするとNULLが返されますが、他の機能。GetProcAddress()でDLLからいくつかの関数を読み込むことができません。

これはコードです。

DLL HEADER(.H)

#include <windows.h> 

extern "C" { 
    __declspec(dllexport) LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam); 
    __declspec(dllexport) int add(int a, int b); 
} 

DLLファイル(.CPP)私はただし、getlを使用している場合

#include "SimpleHook.h" 

extern "C" { 
    __declspec(dllexport) LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam) { 
     return CallNextHookEx(0, code, wParam, lParam); 
    } 

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

MAIN FILE

#include <iostream> 
#include <windows.h> 
#include <tchar.h> 

int main(int argc, char* argv[]) { 
    HINSTANCE dllHandle = LoadLibrary(_T("SimpleHook.dll")); 

    if (dllHandle) { 
     // returns the correct address 
     cout << "add address: " << GetProcAddress(dllHandle, "add") << endl; 

     // returns NULL 
     cout << "hookProc address: " << GetProcAddress(dllHandle, "hookProc") << endl; 
    } 
} 

astError()私は127エラーコードを意味する:

ERROR_PROC_NOT_FOUND:指定されたプロシージャが見つかりませんでした。

奇妙なことは、同じファイルの他の機能が正しく読み込まれていることです。 ご迷惑をおかけして申し訳ございません。

答えて

5

呼び出し規約では、名前の変更が変更されます。 __stdcallの関数は、常に先頭に_という名前が付いていて、他の方法でもマングルされているため、リンクは失敗しますが、__cdecl関数はマングルされていないので、見つけられます。

はあなたが __declspec(dllexport)で構築されたDLLからインポートするには、 常にはあなたがDLLをビルドからもらったのlibをインポートしてリンクしたいすべてのものに __declspec(dllimport)を持つヘッダを含むべきです。これにより、すべての関数が正しくリンクされ、C互換リンクに進む必要がなくなります。

GetProcAddressまたはextern "C"__declspec(dllexport)と組み合わせて使用​​しないでください。

ヘッダー:

#include <windows.h> 

#ifndef MAIN 
#define DLL_API __declspec(dllexport) 
#else 
#define DLL_API __declspec(dllimport) 
#endif 

DLL_API LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam); 
DLL_API int add(int a, int b); 

DLLの.cppファイル:

#include "SimpleHook.h" 

DLL_API LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam) { 
    return CallNextHookEx(0, code, wParam, lParam); 
} 

DLL_API int add(int a, int b) { 
    return a + b; 
} 

メイン.cppファイル:

#define MAIN 
#include "SimpleHook.h" 

int main(int argc, char* argv[]) { 

    if (dllHandle) { 
     // returns the correct address 
     cout << "add address: " << add << endl; 

     // returns NULL 
     cout << "hookProc address: " << hookProc << endl; 
    } 
} 

がリンカにLIBを追加することを忘れないでください。

+0

これにより、 'GetProcAddress'はどのくらい正確に動作しますか? –

+0

@Ben Voigt: '__cedcl'関数はまったく変換されません。私の主なポイントは、GetProcAddressを使用すべきではないということです。 – Puppy

+0

すべての状況で単に 'GetProcAddress'の使用を避けることはできません。また、あなたは盲目的に呼び出し規約を変更することもできません。 –

1

変更された名前を確認するには、dumpbinや依存関係ウォーカーなどのツールを使用する必要があります。

また、リンク時にDEFファイルを使用して、選択した名前をエクスポートテーブルに入れることができます。

3

CALLBACKマクロは__stdcallに解決されます。したがって、アンダースコアを前に付けて、引数のサイズを関数の名前に追加する必要があります。

cout << "hookProc address: " << GetProcAddress(dllHandle, "[email protected]") 
    << endl; 
関連する問題