2

私はC++からアンマネージDLLを参照する方法についての答えを探していました。

C ++でdllをロードするためのより良い方法はありますか?

VisualC++でのDLL参照

また、呼び出し元が.LIBファイルを持っていないと、DLLをC++でロードできないようです。次のように実行時にDLLを動的にロードする場合、.libファイルが絶対に必要であるというのは本当ですか?

   #include <Windows.h>
    HMODULE h;  
    LPCWSTR l;  
    DWORD error;
    wchar_t *myDLL = L"E:\\...\\myWin32DLL.dll";

    l = (LPCWSTR)myDLL;
    h = LoadLibrary(l);     
    error = GetLastError();  

上記のコードを使用してLoadLibraryを呼び出すと、結果はNULLになります。GetLastError()のエラーコードは193:ERROR_BAD_EXE_FORMATです。なんで?

編集/更新: 何が問題なのかを理解しました-プログラムのターゲットプラットフォーム(DLLを呼び出す)をx64として使用し、Win32に変更すると、LoadLibraryがNULL以外の結果を返すようになりました。

DLLは、1つのソースファイルexpFns.cppで構成されています。

#include <Windows.h>

#define Pi 3.14159

extern _declspec(dllexport)  
double circumference(double radius)
{
    return 2.0 * radius * Pi;
}
BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    return TRUE;
}

コンパイル方法は次のとおりです。

cl expFns.cpp /link /DLL /out:mywin32dll.dll

unrar3.DLLなどのよく知られたDLLを使用しても、エラーコード193が表示されます。なぜこのエラーコードが表示されるのですか?

一方、マネージドC#でP / Invokeを使用する場合、必要なのは.DLLへのフルパスだけで、.LIBファイルは必要ありません。DLLへの関数呼び出しは機能します。C ++で.LIBファイルが必要なのに、C#では.LIBファイルが必要ないのはなぜですか?

[DllImport(@"E:\...\myDLL.dll"
            , CallingConvention = CallingConvention.Cdecl
            , EntryPoint = "get_value")]
internal static extern double get_value(double l, double w, double h);
4

3 に答える 3

5

LIBファイルは、静的にリンクする場合にのみ必要です(バイナリとDLLの間に強い依存関係を強制します。DLLが存在しない場合、バイナリはロードされません)。LoadLibrary()(または LoadLibraryEx())はそれをすべてバイパスします:しかし、一方で、GetProcAddress()(またはGetProcAddressEx())を使用して、エクスポートされた関数の序数またはその名前のいずれかを使用して、すべてのエントリポイントへの関数ポインタを設定する必要があります。後者は、C#が行うことでありDllImport、構文はかなりわかりやすいものです。

于 2011-04-24T16:49:33.573 に答える
2

いいえ、実行時に任意のDLLでLoadLibraryを呼び出してからGetProcAddressを呼び出すことができます。DLLに対して静的に(つまり、コンパイル直後に)リンクする場合にのみ.LIBが必要です。

于 2011-04-24T16:49:40.167 に答える
2

.libは__declspec(dllexport)、またはMicrosoftのC++固有のDLLのインポート/エクスポートにのみ使用されます。P / Invokeは.DEFファイルと同じで、CスタイルのDLLインポート/エクスポートであるGetProcAddressを使用します。2つは交換可能ではありません。

于 2011-04-24T17:00:56.617 に答える