1

DllImportを使用してP/Invoke経由でC#からC++DLLを呼び出しています。DLLはサードパーティによって生成され、x86のみです(したがって、C#コードもx86としてビルドされます)。

コンソールアプリケーションからDLLの特定の関数を呼び出すと、常に正しい結果が1つ得られます。この関数はファイルパスを取得し、ファイルからいくつかの情報を抽出します。

関数のシグネチャは次のとおりです。

private static extern int Function(
    string str1,
    int bool1,
    ref uint outUint1,
    ref uint outUint2,
    ref uint outUint3,
    ref double outDouble1,
    ref double outDouble2,
    StringBuilder outStr1);

そして、予期しない結果がref uintパラメータの1つにあります。

単体テストを作成し、まったく同じコード(すべてのパラメーターとそのようなハードコードを含む)を呼び出すと、まったく異なる結果が得られますが、これは正しくありません。間違った結果は常に同じです。さまざまな異なるランナーを使用してMSTestテストとNUnitテストの両方を試しましたが、同じ結果になりました。

正しい結果が得られるケース:

  • コンソールアプリ
  • Winformsアプリ
  • コードを実行しているが、単体テスト(NUnit)から起動されたコンソールアプリ

誤った結果を生成するケース:

  • Resharper Test Runner(NUnit)からのテスト実行
  • Visual Studio Test Runner(MSTest)からのテスト実行
  • NUnitGUIテストランナーからのテスト実行
  • NUnitコンソールテストランナーからのテスト実行

私のテスト環境はWindows8で、C#は.NETFramework4をターゲットとするx86用に構築されています。

この問題の原因や、さらにデバッグするために私ができることについて何か考えがありますか?

私は間違いなくDLLを作成したサードパーティに連絡しようとしますが、この問題の原因を正確に把握しておくと、問題が解決する可能性が大幅に高まります。

4

1 に答える 1

1

予想される「ファイルパス」が作業ディレクトリに相対的であるか、作業ディレクトリまたはアプリケーションディレクトリでさえdllにとって重要であるように思われます。

そのdllは、そのディレクトリ内の他のdllを参照しようとする場合もありますが、そのディレクトリで実行されているexeではなく、独自のフォルダからロードされたため、それらを見つけることができません。

このページの約半分で、dll解決の検索順序について説明しています。

  1. アプリケーションがロードされたディレクトリ。

  2. 現在のディレクトリ。

  3. システムディレクトリ。GetSystemDirectory関数を使用して、このディレクトリのパスを取得します。

  4. 16ビットシステムディレクトリ。このディレクトリのパスを取得する関数はありませんが、検索されます。

  5. Windowsディレクトリ。GetWindowsDirectory関数を使用して、このディレクトリのパスを取得します。

  6. PATH環境変数にリストされているディレクトリー。これには、AppPathsレジストリキーで指定されたアプリケーションごとのパスは含まれないことに注意してください。DLL検索パスを計算する場合、AppPathsキーは使用されません。

お役に立てば幸いです。

編集:別のアイデア...正しい値を返すようにそのDLLのラッパーを作成し、ラッパーに組み込まれているユニットテスターと連携するインターフェイスを作成することができます。

于 2012-11-09T20:15:41.363 に答える