2016-04-01 23 views
-2

いくつかのネイティブDLLのC++/CLIラッパーを作成しようとしています。 これらのDLLは今後7つありますので、動的にロードする必要があります。それらはすべて同じ機能を持っています。 LoadLibraryとGetProcAddressは、ネイティブアプリケーションでこれらの関数を読み込むのに効果的でした。ネイティブ関数のラッパー

DLLを読み込んでInitializeを呼び出すたびに、私はAccessViolationExceptionを取得します。 プラットフォームのx86を選択したC#コンソールアプリケーションでテストします。

更新: 私が投票した理由はわかりません。この質問は私のGoogle検索のいずれにおいても答えられていません。私は尋ねる前に半週間も探しました。同じことについてここでのすべての質問は、別の方法を使用しています。 MSDNでは、ネイティブinteropでのアクセス違反は深刻なプログラミングエラーの兆候であると言います。私は何が間違っているのか分かりません。私は文字列をマーシャリングし、呼び出し前にnullptrをチェックしています。負荷機能が機能しているようです。私が知られている悪い関数名を入れた場合、または私が知っているDLLパスが間違っていると、読み込みに失敗したことがわかります。私は正しいパス/関数名を入れれば、それはすべてが働いたと言うが、私はそれを呼び出すときにクラッシュする。私がテストしているDLLの関数TSInitは実際にはこの特定のDLLで何もしませんが、同じインタフェースを持つ他のDLLに対しては実際の作業を行う可能性があります。

アップデート2:

私はこの質問がunanswerableだと思います。私が言ったように、まったく同じインターフェイスを持ついくつかのDLLがあります。今、私はそれらのいくつかが働くことを見つけました、そしていくつかは働きません。私はダンプビンで全部チェックして、コンパイルされたすべてのx86であることを確認した。私は、動作しないDLLに何が間違っているのかよく分かりません。ネイティブのC++アプリケーションでは、すべて期待どおりに動作します。

typedef long (WINAPI *TSRINIT)(long lType, HWND hParent, RECT *pRect); 

namespace Imagery 
{ 
    public ref class Recongizer 
{ 
public: 
    Recongizer(String^ DllPath) { LoadRecongizer(DllPath); } 
    ~Recongizer() { UnloadLibrary(); } 
    bool LoadRecongizer(String^ DllPath) 
    { 
     HInstance = ::LoadLibrary(msclr::interop::marshal_as<std::wstring>(DllPath).c_str()); 
     if (HInstance == nullptr) return false; 
     if (!LoadFunctions()) return false; 
     return true; 
    } 
    long Initalize(long lType) 
    { 
     if (HInstance == nullptr || TSInit == nullptr) return 0; 
     return TSInit(0, nullptr, nullptr); 
    } 
private: 
    void UnloadLibrary() 
    { 
     if (HInstance != nullptr) ::FreeLibrary(HInstance); 
    } 
    bool LoadFunctions() 
    { 
     TSInit = (TSRINIT)::GetProcAddress(HInstance, "TSRInit"); 
     if (TSInit == nullptr) 
     { 
      ErrorMessage = "TSRInit could not be loaded."; 
      return false; 
     } 
     return true; 
    } 
    property String^ ErrorMessage; 
private: 
    HINSTANCE HInstance{ nullptr }; 
    TSRINIT TSInit{ nullptr }; 
}; 

}

+0

このような漠然とした質問の診断を得ることはできません。 * LoadLibrary()を使用しないで*始めると、そこには全くポイントがありません。これらのDLLのインポートライブラリをリンクし、関連する.hファイルを#includeします。 3つの障害モードが少なくなりました。 –

+0

アクセス違反は魔法ではありません。たとえば、スタックトレースがあります。 – MSalters

答えて

0

これは、呼び出し規約に問題がある可能性があります。すべてのDLLが同じ呼び出し規約(つまり、の定義に従ってWINAPI)を使用していることを確認してください。そうしないと、コードとしてスタックの破損が発生し、DLLのコードによって異なるクリーンアップ動作が発生する可能性があります。概要については、https://msdn.microsoft.com/en-us/library/984x0h58.aspxを参照してください。ネイティブのC++アプリケーションがなぜ機能するのかはわかりませんが、それはちょっと野性的なものです。

関連する問題