質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

14095閲覧

C#からDLLの関数でエラー「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。」

moto-a

総合スコア17

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

2クリップ

投稿2018/08/27 05:29

編集2018/08/27 08:25

お世話になります。
C#からDLLの関数を実行した時にエラーが発生してしまいます。
エラー原因や怪しそうなところがありましたら教えてください。
また「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。」というエラーはどういった時に発生しますでしょうか?

【ソース】
BioAPI_IdentifyMatchで以下のエラーがでます。

C#

1BioAPI_HANDLE ModuleHandle = 0; 2BioAPI_FAR MaxFARRequested = null; 3BioAPI_FRR MaxFRRRequested = null; 4BioAPI_BOOL FARPrecedence = null; 5BioAPI_INPUT_BIR ProcessedBIR = null; 6BioAPI_IDENTIFY_POPULATION Population = null; 7BioAPI_BOOL Binning = null; 8uint MaxNumberOfResults; 9uint NumberOfResults; 10BioAPI_CANDIDATE [] Candidates = null; 11int Timeout = 30000 12 13BioAPI_RETURN bReturn = BioAPI_RETURN.BioAPI_ERRCODE_INTERNAL_ERROR; 14IntPtr ptrMaxFRRRequested = IntPtr.Zero; 15BioAPI_INPUT_BIR_Marshal mProcessedBIR = null; 16IntPtr ptrCandidates = IntPtr.Zero; 17if (MaxFRRRequested >= (BioAPI_FRR) 0) 18{ ptrMaxFRRRequested = BioAPIWin32.MarshalInt32((int) MaxFRRRequested); } 19if (ProcessedBIR != null) 20{ mProcessedBIR = new BioAPI_INPUT_BIR_Marshal(ProcessedBIR); } 21 22bReturn = BioAPIWin32.BioAPI_IdentifyMatch( 23 ModuleHandle, 24    ref MaxFARRequested, 25 ptrMaxFRRRequested, 26 ref FARPrecedence, 27 mProcessedBIR, 28 ref Population, 29 Binning, 30 MaxNumberOfResults, 31 ref NumberOfResults, 32 ptrCandidates, 33 Timeout);

■BioAPI_IdentifyMatchの定義

C#

1[DllImport("bioapi100.dll")] 2public static extern BioAPI_RETURN BioAPI_IdentifyMatch( 3 BioAPI_HANDLE ModuleHandle, ref BioAPI_FAR MaxFARRequested, 4 IntPtr ptrMaxFRRRequested, ref BioAPI_BOOL FARPrecedence, 5 BioAPI_INPUT_BIR_Marshal ProcessedBIR, 6 ref BioAPI_IDENTIFY_POPULATION Population, 7 BioAPI_BOOL Binning, 8 uint MaxNumberOfResults, 9 [In, Out]ref uint NumberOfResults, 10 [In, Out] IntPtr ptrCandidates, 11 int Timeout);

Cの仕様

C

1BioAPI_RETURN BioAPI BioAPI_IdentifyMatch ( 2BioAPI_HANDLE ModuleHandle, 3const BioAPI_FAR *MaxFARRequested, 4const BioAPI_FRR *MaxFRRRequested, 5const BioAPI_BOOL *FARPrecedence, 6const BioAPI_INPUT_BIR *ProcessedBIR, 7const BioAPI_IDENTIFY_POPULATION *Population 8BioAPI_BOOL Binning, 9uint32 MaxNumberOfResults, 10uint32 *NumberOfResults, 11BioAPI_CANDIDATE_ARRAY_PTR *Candidates, 12sint32 Timeout 13);

【追加質問】
PopulationとNumberOfResultsがポインタになっているにも関わらずDllimportではrefになっていますが、良いでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2018/08/27 05:52

ソースコードは、<code>ボタン押して、’’’の枠の中に貼り付けてください
Zuishin

2018/08/27 08:20

C のヘッダとかマニュアルとか無いんでしょうか? 呼び出し規約は合っていますか?
guest

回答1

0

ベストアンサー

PopulationとNumberOfResultsがポインタになっているにも関わらずDllimportではrefになっていますが、良いでしょうか?

こういう質問が出るくらいなのでメソッド宣言については自作ではなく信頼性の高いものを使っているのだと思います。
ですから宣言は合っているとみなして考えます。
ポインタを参照にマーシャリングするのは問題ありません。普通そうします。

問題は ModuleHandle や
ptrMaxFRRRequested などに正しい値が渡っているかどうかです。
呼び出す前にブレークポイントを置いて全ての引数に正しい値が入っているかどうか確かめてください。
正しいかどうかはこちらではわかりません。
適当に使うのではなくその API の使い方をあらかじめ勉強して熟知してから使ってください。

bio100 ということは Bio_100% でしょうか。古いものだと思うので今から使うには根性がいりそうです。
そもそも使わないという選択肢も視野に入れてください。

投稿2018/08/27 08:39

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moto-a

2018/08/27 09:48 編集

ModuleHandle,ptrMaxFRRRequested は想定の値でした。 他社製DLLをデバッグやエラーしている引数を確認する方法はありますでしょうか?現状では見当がつかないため、ヒントになるものがあればと思います。
Zuishin

2018/08/27 09:50

他の引数も調べてください。 その想定の値を渡していいかどうかも。 十中八九 dll でなく呼び出しコードに問題があります。
moto-a

2018/08/29 05:19

ご回答ありがとうございます。まちがいなく引数に問題があると思います。 特にあやしいと思われる引数 「BioAPI_CANDIDATE_ARRAY_PTR *Candidates」 これをC#側で 「[In, Out] IntPtr ptrCandidates」 としています。 Candidatesは結果が返ってくる配列ですが、 IntPtr ptrCandidates = IntPtr.Zero; とnullを渡しています。 これがAccessViolationException を起こしているとにらんでいます。 BioAPI_CANDIDATE_ARRAYの仕様は typedef struct bioapi_candidate { BioAPI_IDENTIFY_POPULATION_TYPE Type; union { BioAPI_UUID_PTR BIRInDataBase; uint32 *BIRInArray; } BIR; BioAPI_FAR FARAchieved; BioAPI_FRR FRRAchieved; } BioAPI_CANDIDATE, *BioAPI_CANDIDATE_PTR; typedef BioAPI_CANDIDATE_PTR BioAPI_CANDIDATE_ARRAY, *BioAPI_CANDIDATE_ARRAY_PTR; です。 なにかお気付きの点がありましたらよろしくお願いします。
Zuishin

2018/08/29 05:38

その API の仕様がわからないので何とも。 配列の参照に IntPtr.Zero を渡すこと自体は昔の API でよく見られるものだったのでそこまで奇異には思いません。 API のマニュアルを読んでしっかりと仕様を確認して失敗しない引数を渡して試し、それを少しずつ変えながらどうしたら失敗するかを確かめてみたらどうでしょうか?
moto-a

2018/08/29 06:10

ご回答ありがとうございました。残念ながら詳しい仕様がありません。 BioAPI_CANDIDATE_ARRAYは結果が返る配列にも関わらず、IntPrt.Zeroで渡しています。事前メモリ確保が必要なのかと思いました。
moto-a

2018/08/31 11:28

解決はしていませんが、VC++からは問題なくAPIを呼び出すことができましたのでVC++でWrapperDLLを作成する形にしました。 一旦終了とさせていただきます。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問