2

LabVIEW 内で DLL を呼び出すと、アクセス違反が発生します。DLL を「extcode.dll」と呼びましょう。私はそのコードを持っていません。それは外部の製造業者からのものです。

Windbg で実行すると、次のメッセージで停止しました。

(724.1200): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll!RtlNewSecurityObjectWithMultipleInheritance+0x12a:

コールスタックは次のとおりです。

ntdll!RtlNewSecurityObjectWithMultipleInheritance+0x12a
ntdll!MD5Final+0xedfc
ntdll!RtlFindClearBitsAndSet+0xdf4
ntdll!RtlFindClearBitsAndSet+0x3a8
ntdll!RtlFindClearBitsAndSet+0x4b9
ntdll!RtlCreateProcessParametersEx+0x829
ntdll!LdrLoadDll+0x9e
KERNELBASE!LoadLibraryExW+0x19c
KERNELBASE!LoadLibraryExA+0x51
LabVIEW!ChangeVINameWrapper+0x36f5
LabVIEW!ChangeVINameWrapper+0x3970
LabVIEW!ExtFuncDynLibWrapper+0x211

アクセス違反の前に、extcode.dll の依存関係が読み込まれることに注意してください。

状況はランダムですが、それが発生すると、後続のすべての試行がそれにつながります。

コードは、DLL 内の関数を呼び出す単純な LabVIEW 関数であり、プロトタイプは非常に単純 ( int function(void)) であるため、呼び出しパラメータの設定ミスやポインタ演算ではありません。呼び出し規約とエラー チェック レベルのすべての組み合わせをチェックしました。

他の環境 (.NET および C) で呼び出された場合、DLL は完全に正常に動作します。

RtlFindClearBitsAndSetビット配列操作に関連していることがわかりました

それはあなたに何を考えさせますか?extcode.dll、LabVIEW、または Windows に問題があると思いますか?

PS: Windows 7 64 ビット (extcode.dll は 64 ビット) で LabVIEW 2010 64 ビットを使用しています。32ビットシステムで再現できませんでした。

11/18 編集

最終的に、DLL をラップするスタンドアロンの exe を作成しました。LabVIEWはパイプを介して通信します。完全に動作しますが、LabVIEW に DLL をロードするとクラッシュする理由がわかりません。

4

5 に答える 5

1

C から呼び出されたときに正常に動作する場合、DLL はおそらく正常であるため、Windbg での作業を終了できます。DLL の呼び出し方法に問題があり、DLL が LabView のメモリの一部を上書きすると、実際に問題が発生するまでに 1000 回の反復が必要になる場合でも、DLL はすべて終了します。

最初に呼び出し規約、C または StdCall を確認してください。C 呼び出し規則がデフォルトであり、StdCall はほぼ確実に必要なものです。(DLL ヘッダー ファイルを確認してください。) LabView 2009 では、呼び出し規則の自動チェックと修正が行われたようですが、LV 2010 で LLVM に切り替えられたため、これが不可能になりました。今はただの戦車です。

これを変更してもまだタンクになる場合は、呼び出し引数をもう一度確認してください。何を渡すか、スカラーまたはポインターデータ? LabView でメモリ (つまり、バイト配列) を割り当て、そのポインタを DLL に渡して変更することはできますが、LabView から DLL によって割り当てられたメモリにアクセスすることはできません。

また、DLL への以前の呼び出しからポインター (refnum など) を取得し、それを返す場合は、ポインターのサイズを確認してください。LabView の Call Library 関数に「ポインタ サイズ整数」型が追加されました。これは、LabView が 32 ビットまたは 64 ビットのどちらで呼び出されたかに応じて、適切なサイズの型を生成します。(コンパイル時に定義する必要があるため、ネットワーク上では常に 64 ビットです。) DLL が 32 ビットで動作するという事実は、これが可能であることを示唆しています。

また、C 構造体は (C) コンパイラによって整列されることが多いことにも注意してください。Uint8 と UInt16 で構成された構造体へのポインタを渡す場合、C コンパイラはこれに 32 ビット (場合によっては 64 ビット) を割り当てます。LabView で構造体 (クラスター) をパディングして一致させるか、ラッパー DLL を記述して構造体をアセンブルする必要があります。

-ロブ

于 2010-11-05T14:59:15.877 に答える
1

コンピューターでDEP (データ実行防止) が有効になっていて、バイナリ (EXE または DLL) が実行しようとしている何かを承認しない場合、アクセス違反 (0xc0000005) も報告されます。通常、 DEPは Windows XP ではデフォルトでオフになっていますが、Windows Vista / Windows 7 ではアクティブになっています。

DEPはハードウェアでサポートされているセキュリティ対策であり、以前は「一部のデータ」と見なされていた一部のバイトを悪意のあるコードが実行するのを防ぐように設計されています。私はそれでいくつかの慣らし運転がありましたが、そのすべてで、問題のあるバイナリを最近のバージョンの Microsoft Visual Studio で再コンパイルする必要がありました。これにより、バイナリがDEPをサポートするかどうかを定義するフラグを設定できます。

役立つリソース:

于 2011-03-04T11:18:26.927 に答える
0

試してみるもう 1 つのこと: DLL 呼び出しを右クリックし、[構成] を選択して、任意のスレッドではなく UI スレッドで実行していることを確認します。時々これが役立ちます。

于 2010-11-18T15:34:05.023 に答える
0

これをリモートで診断するのは困難ですが、いくつかのアイデアがあります。

関数が引数を取らないという事実は、関数が本当に自明であるか、以前の関数呼び出しを考慮した状態が dll に格納されていることを意味します。この関数のクラッシュは指標に過ぎず、以前の関数呼び出しに問題があるのではないでしょうか? 呼び出していない初期化ルーチンはありますか?

64 ビットの labview を使用しているときにのみ問題が発生する場合、私の最初の推測では、DLL の 64 ビット バージョンに問題があると思われますが、DLL を使用する場合とまったく同じ呼び出しで問題がないと確信している場合は、他の環境では、私は困惑しています。1 つの可能性は、labview で間違った呼び出し規約 (stdcall と cdecl) を使用している可能性があります。

labviewインポートウィザードを使用してdllとヘッダーをインポートしようとしましたか? これは、プロトタイプでのばかげた間違いを避けるのに役立つかもしれません。

于 2010-11-08T13:59:16.720 に答える