C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: 引数にポインタが含まれているAPIをVB.NETで読み出す


(過去ログ 113 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■66712 / inTopicNo.1)  引数にポインタが含まれているAPIをVB.NETで読み出す
  
□投稿者/ くまくま (1回)-(2013/05/18(Sat) 16:41:47)

分類:[VB.NET/VB2005 以降] 

OSはXPで、VB2005を使用しています。

Cか何かで作成したDLLに以下のようなAPI関数があります。

ファイル名 sample.dll
typedef struct{
 byte ad[4];
 word no;
 byte rev[2]
}LPconf;

long LP_Open(long ID , LPconf* conf);

VB2005でこのAPIを読み出して操作をしたいのです。
以下のようなコードで呼び出しました。

Imports System.Runtime.InteropServices
Module Module03
 <StructLayout(LayoutKind.Sequential)> Public Structure str_conf0
  <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Public Vadd As Byte()
  <MarshalAs(UnmanagedType.U2)> Public Vno As UShort
  <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Public Vrev As Byte()
 End Structure

 <DllImport("sample.dll")> _
  Public Function LP_Open( _
    ByVal ID As Long, ByRef conf As str_conf0) As Long
  End Function
End Module

Formにボタンを配置して、LP_Openを実行したところ、VBとしてエラーは出てないのですが、関数からは「不正なパラメータが渡された」というエラーが返ってきました。
これ以外にもいろいろ試してみたのですが、どれもこれも同じエラーとなります。

どこか間違っているところはありませんか?
引用返信 編集キー/
■66714 / inTopicNo.2)  Re[1]: 引数にポインタが含まれているAPIをVB.NETで読み出す
□投稿者/ 魔界の仮面弁士 (218回)-(2013/05/18(Sat) 17:22:37)
No66712 (くまくま さん) に返信
> long LP_Open(long ID , LPconf* conf);
この long 型は 32bitですか? 64bit ですか? (処理系によって異なります)
http://www9.plala.or.jp/sgwr-t/c/sec13.html
http://j.mp/IntegerType

たとえば下記(Windows SDK のデータ型)では、long および LONG 型は、
32bitの符号付整数型であると記されています。
http://msdn.microsoft.com/ja-jp/library/aa383751.aspx

64bitなら、As Long で宣言することもできますが、
32bitなら、As Integer にせねばなりません。


> Formにボタンを配置して、LP_Openを実行したところ、
呼び出す前に、配列メンバーを初期化していますか?

C# とは異なり、VB.NET では固定サイズの配列を作れないので、
コンストラクタ等を通じて、ReDim なり New なりを用いて、
SizeConst に指定した分の配列要素を確保しておく必要があります。

ただし構造体の場合、既定のコンストラクタを変更できません。
そのため、構造体のかわりにクラスを使うのも一つの選択肢となりえます。
(構造体をByRefで渡す代わりに、クラスをByValで渡すようにする)
引用返信 編集キー/
■66715 / inTopicNo.3)  Re[2]: 引数にポインタが含まれているAPIをVB.NETで読み出す
□投稿者/ くまくま (2回)-(2013/05/18(Sat) 17:51:55)
回答ありがとうございます。
それは気が付きませんでした。

APIはLongは符号付32bitでした。
ちなみに、wordは符号なし16bitです。
Long型を全部Integerに変えました。
それでも、エラーコードは変わりませんでした。

ボタンを押してのコードは以下の通りです。
Private Sub Button1_Click(・・・以下略)
Dim Ret as Integer
Dim conf as str_conf0

Ret = LP_Initilal() '…DLLの初期化
conf.Vadd = New Byte(3) {CByte(35), CByte(69), CByte(6), CByte(1)}
conf.Vno = CUShort(12345)
conf.Vrev = New Byte(1) {CByte(0), CByte(0)}
Ret = LP_Open(0,conf)
End Sub

以上ですが、どこかおかしいところありますか?
引用返信 編集キー/
■66716 / inTopicNo.4)  Re[3]: 引数にポインタが含まれているAPIをVB.NETで読み出す
□投稿者/ 魔界の仮面弁士 (219回)-(2013/05/18(Sat) 19:31:54)
2013/05/18(Sat) 20:36:04 編集(投稿者)

No66715 (くまくま さん) に返信
> それは気が付きませんでした。
どっちのことでしょうか? <「それ」


> APIはLongは符号付32bitでした。
API は long でも LONG でもなく、Long だったのでしょうか?


> Long型を全部Integerに変えました。
> それでも、エラーコードは変わりませんでした。
第2引数が LPconf でも conf* でもなく LPconf* になっているので、
構造体ポインタへの参照を渡すことが要求されているとか……?
もしそうであれば、 Structure から Class に変更してみるとか。

ただ、構造体そのものが conf ではなく LPconf 定義になっているので
外しているような気がしないでもないという。ちょっと自信無し。


> conf.Vno = CUShort(12345)
リテラル表記で、
 conf.Vno = 12345US
とも書けますね。
引用返信 編集キー/
■66717 / inTopicNo.5)  Re[4]: 引数にポインタが含まれているAPI
□投稿者/ Azulean (164回)-(2013/05/18(Sat) 22:08:36)
2013/05/19(Sun) 08:39:23 編集(投稿者)

No66716 (魔界の仮面弁士 さん) に返信
> 第2引数が LPconf でも conf* でもなく LPconf* になっているので、
> 構造体ポインタへの参照を渡すことが要求されているとか……?

C 言語のあの書き方の場合、LPconf となっていますが、ポインタではないです。(紛らわしい命名だとは思いますが…)
従って、LPconf* という場合、単に構造体のポインタです。

// LP で始めるポインタ型なら、typedef struct { /* 略 */ } CONF, *LPCONF; と言うように、識別子の前に * が必要になります、念のため。


No66715 (くまくま さん) に返信
> 以上ですが、どこかおかしいところありますか?

見えている材料では推測が難しいかなと感じています。
VB.NET で書かれているのと同等の C 言語、あるいは C++ から呼ぶサンプルは提示できますか?
構造体、関数の宣言の問題なのか、それらは合っていて構造体に入れる値の問題なのか、わからないためです。
引用返信 編集キー/
■66718 / inTopicNo.6)  Re[5]: 引数にポインタが含まれているAPIをVB.NETで読み出す
□投稿者/ 魔界の仮面弁士 (220回)-(2013/05/19(Sun) 00:30:38)
No66717 (Azulean さん) に返信
> C 言語のあの書き方の場合、LPconf となっていますが、ポインタではないです。
ですよね…。
掲示板投稿時の転記上の問題かとも思って一応書いては見たものの、
正直外している感が捨てきれず。


DLL 側をデバッグして、どのようなデータが渡されているか確認できれば
何かわかるかも知れませんが、コード的には特に問題なさそうに見えます。
構造体も、メンバー構成的にパディングの問題も起きにくそうですし。

あと調べるとすれば、CallingConvention ぐらいですかね…。

>>>> 関数からは「不正なパラメータが渡された」というエラーが
これは、関数の戻り値(エラーコード?)から示されているのでしょうか。

宣言自体が問題なのではなく、関数の呼び出し手順または構造体メンバーに設定した値に
問題があって、パラメータエラーとして扱われているという可能性はありませんか?
引用返信 編集キー/
■66725 / inTopicNo.7)  Re[6]: 引数にポインタが含まれているAPIをVB.NETで読み出す
□投稿者/ くまくま (3回)-(2013/05/20(Mon) 09:30:53)
皆様ありがとうございました。
何とか、うまくできました。

テスト中故のの大バカなことをしていました。
結論を言えば、Longを全部Int32に変えたと思っていたのですが、変えたのは#if 0…で使えなくしていた部分でした。
なんか、ものすごく、すいません。

ありがとうございました。
classで渡すというのは思いつかなかったし、本当は知っておかなきゃいけないんだろうけど、今までclassは避けていたのでそういうわけにはいかないなと思いました。
解決済み
引用返信 編集キー/
■66726 / inTopicNo.8)  Re[7]: 引数にポインタが含まれているAPIをVB.NETで読み出す
□投稿者/ 魔界の仮面弁士 (221回)-(2013/05/20(Mon) 10:13:23)
No66725 (くまくま さん) に返信
> 変えたのは#if 0…で使えなくしていた部分でした。

今後、使用される VB のバージョンを更新しておくと、今回のようなミスを減らせますよ。

『VB2010 以降』をお使いになれば、#If ディレクティブでコンパイル対象外として
除外されたコードが淡色表示となるためです。(デフォルト設定では薄い灰色の文字)


> なんか、ものすごく、すいません。

解決したようで良かったです。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -