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

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

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

Re[5]: VB.NETからVC作成DLLの関数を使用する際の引数


(過去ログ 27 を表示中)

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

■12773 / inTopicNo.1)  VB.NETからVC作成DLLの関数を使用する際の引数
  
□投稿者/ リバー (1回)-(2008/01/17(Thu) 13:54:18)

分類:[VB.NET/VB2005] 

2008/01/17(Thu) 14:29:39 編集(投稿者)

初めましてリバーと申します。

現在、VB.NET2003からVC++6.0作成DLLの関数を使用することに挑戦しています。

VC作成DLLの関数の引数は1:構造体のポインタ、2:LPSTRです。
構造体:
1番目の項目の型:void*
2番目の項目の型:int
3番目の項目の型:int
4番目の項目の型:構造体A
5番目の項目の型:int
6番目の項目の型:int
7番目の項目の型:int

構造体A:
1番目の項目の型:int
2番目の項目の型:int
3番目の項目の型:int
4番目の項目の型:int
5番目の項目の型:int
6番目の項目の型:int
7番目の項目の型:int
8番目の項目の型:int
9番目の項目の型:int


VB記述内容:
Public Structure 構造体
Public NoA As IntPtr
Public NoB As Integer
Public NoC As Integer
Public NoD As 構造体A
Public NoE As Integer
Public NoF As Integer
Public NoG As Integer
End Structure

Public Structure 構造体A
Public NoA As Integer
Public NoB As Integer
Public NoC As Integer
Public NoD As Integer
Public NoE As Integer
Public NoF As Integer
Public NoG As Integer
Public NoH As Integer
Public NoI As Integer
End Structure

Private Declare Auto Function 関数名 Lib "DLL名フルパス" _
(ByRef _構造体 As 構造体, ByVal LpStr As String) As Long

Public Sub test()
Dim _構造体 As New 構造体
Dim _構造体A As New 構造体A
Dim 戻り値用変数 As Long

構造体、構造体Aの値設定

戻り値用変数 = 関数名(構造体, "文字列")

End Sub

上記のようにプログラムを記述しています。
関数の呼び出しは成功していますが、
関数の戻り値が想定外の値になって返ってきます。
構造体の1番目の項目の型:void*をVB側でIntPtr型で
宣言している箇所が怪しいと考えていますが、
実際どこが間違っていてどう修正するべきかわかりません。

上記プログラムについて間違っている箇所、修正するべき箇所について
ご指摘を宜しくお願い致します。

引用返信 編集キー/
■12774 / inTopicNo.2)  Re[1]: VB.NETからVC作成DLLの関数を使用する際の引数
□投稿者/ 魔界の仮面弁士 (572回)-(2008/01/17(Thu) 14:08:15)
2008/01/17(Thu) 14:09:13 編集(投稿者)
No12773 (リバー さん) に返信
>     Public Structure 構造体
StructLayout 属性を指定して、Pack サイズを明示した方が無難かも知れません。
(デフォルトでは 8 バイトパッキングなので)

>     Private Declare Auto Function 関数名 Lib "DLL名フルパス" _
>                (ByRef _構造体 As 構造体, ByVal LpStr As String) As Long
戻り値が Int64 型になっていますが、これは間違いありませんか?

>         戻り値用変数 = 関数名(構造体, "文字列")
第2引数は、LPCSTR ではなく、LPSTR なのですよね。
であれば文字列リテラルでは無く、String 変数を指定した方が良いかも。

引用返信 編集キー/
■12776 / inTopicNo.3)  Re[1]: VB.NETからVC作成DLLの関数を使用する際の引数
□投稿者/ よねKEN (104回)-(2008/01/17(Thu) 14:19:49)
私に回答できるかどうかは別として、
質問内容にいくつか不明点がありますので確認させてください。
後、気になる点についてもコメントします。

○気になる点
・各構造体にはStructLayout属性を付加した方がよいかもしれません。
・Declareで宣言している関数の戻り値は64ビット型のLongでよいのでしょうか?
 Integerが適切だったりはしませんか?
・文字列はLPSTRとのことですが、ならばAutoでなくAnsiではないでしょうか。

○確認したい点
> 関数の呼び出しは成功していますが、
> 関数の戻り値が想定外の値になって返ってきます。

ここで言う戻り値というのはどれのことでしょうか?
文脈からすると「ByRef _構造体 As 構造体」の部分に対する物を指しているようですが・・・。
Declare文最後のAs Longは戻り値ですし、
ByVal LpStr As StringもLPCSTRじゃないので戻り値かもしれませんし。

> 構造体の1番目の項目の型:void*をVB側でIntPtr型で
> 宣言している箇所が怪しいと考えていますが、
> 実際どこが間違っていてどう修正するべきかわかりません。

ご提示の情報からは何が間違っているのかを判断できないように思いますので、

・VC++6側のソースコードはどんな感じの作りなのでしょうか?
・そちらの動作に問題ないことは確認が取れているのでしょうか?
・どんな値が返ってくると考えて、実際はどんな値が返ってきたのでしょうか?

といった情報も追加でご提示ください。

#この辺は私は得意分野ではないので答えられるかどうかはわかりませんが、
#そっちが得意な方にとっても必要な情報だと思います。

引用返信 編集キー/
■12777 / inTopicNo.4)  Re[2]: VB.NETからVC作成DLLの関数を使用する際の引数
□投稿者/ リバー (3回)-(2008/01/17(Thu) 15:03:38)

魔界の仮面弁士さん、
よねKENさん
早速の回答ありがとうございます。

魔界の仮面弁士さんへ
> StructLayout 属性を指定して、Pack サイズを明示した方が無難かも知れません。
> (デフォルトでは 8 バイトパッキングなので)
  構造体の定義部に
<StructLayout(LayoutKind.Sequential, Pack:=8, CharSet:=CharSet.Auto)> _
  を付与しました。
>
> 戻り値が Int64 型になっていますが、これは間違いありませんか?
>
戻り値の指定が誤っていました。
Integer型に変更したところ戻り値としては正しい値が返ってきました。


> 第2引数は、LPCSTR ではなく、LPSTR なのですよね。
> であれば文字列リテラルでは無く、String 変数を指定した方が良いかも。
String変数を宣言し、指定するように修正しました。



よねKENさんへ
> ○気になる点
> ・各構造体にはStructLayout属性を付加した方がよいかもしれません。
  構造体の定義部に
<StructLayout(LayoutKind.Sequential, Pack:=8, CharSet:=CharSet.Auto)> _
  を付与しました。

> ・Declareで宣言している関数の戻り値は64ビット型のLongでよいのでしょうか?
>  Integerが適切だったりはしませんか?
Integer型に変更したところ戻り値としては正しい値が返ってきました。

> ・文字列はLPSTRとのことですが、ならばAutoでなくAnsiではないでしょうか。
AutoをAnsiに変更しましたが実行結果は同じでした。


> ○確認したい点
>>関数の呼び出しは成功していますが、
>>関数の戻り値が想定外の値になって返ってきます。
>
> ここで言う戻り値というのはどれのことでしょうか?
> 文脈からすると「ByRef _構造体 As 構造体」の部分に対する物を指しているようですが・・・。
> Declare文最後のAs Longは戻り値ですし、
> ByVal LpStr As StringもLPCSTRじゃないので戻り値かもしれませんし。
>
>>構造体の1番目の項目の型:void*をVB側でIntPtr型で
>>宣言している箇所が怪しいと考えていますが、
>>実際どこが間違っていてどう修正するべきかわかりません。
>
> ご提示の情報からは何が間違っているのかを判断できないように思いますので、
>
> ・VC++6側のソースコードはどんな感じの作りなのでしょうか?
> ・そちらの動作に問題ないことは確認が取れているのでしょうか?
> ・どんな値が返ってくると考えて、実際はどんな値が返ってきたのでしょうか?
>
> といった情報も追加でご提示ください。
>
> #この辺は私は得意分野ではないので答えられるかどうかはわかりませんが、
> #そっちが得意な方にとっても必要な情報だと思います。
>

使用する関数の定義としては
引数:

構造体*(ポインタ) I/O
LPSTR I
と定義されていて引数とは別に
戻り値があります。

戻り値の値は
0:正常終了
1:パラメータエラー
2:実行エラー
となっています。

戻り値の型をIntegerに変更する前は0、1、2以外の値が返ってきました。
戻り値の型をIntegerに変更した後は1:パラメータエラーが返ってきました。

パラメータエラーが発生しているということは
VCのソースコードを確認したほうがよさそうですね。

VCのソースコードが手元にないので入手し、調査してみます。
解決次第報告させていただきます。


引用返信 編集キー/
■12778 / inTopicNo.5)  Re[3]: VB.NETからVC作成DLLの関数を使用する際の引数
□投稿者/ 魔界の仮面弁士 (573回)-(2008/01/17(Thu) 15:28:37)
No12777 (リバー さん) に返信
>>StructLayout 属性を指定して、Pack サイズを明示した方が無難かも知れません。
>>(デフォルトでは 8 バイトパッキングなので)
>   構造体の定義部に
> <StructLayout(LayoutKind.Sequential, Pack:=8, CharSet:=CharSet.Auto)> _
>   を付与しました。
Pack:=8 で正しいのかどうかは、確認されましたか?
(VC 側で、#pragma pack 指定や、pshpack1.h 等が #include されていたりはしませんね?)

あと、DLL が Unicode コンパイルなのかどうかも確認しておいた方が良いでしょう。
文字列が LPWSTR や LPTSTR ではなく、LPSTR ということになると、
CharSet.Auto では不味いかも知れませんし。

>>第2引数は、LPCSTR ではなく、LPSTR なのですよね。
>>であれば文字列リテラルでは無く、String 変数を指定した方が良いかも。
> String変数を宣言し、指定するように修正しました。
DLL 側が LPSTR という点は、間違い無いのですね?
http://www.usefullcode.net/2006/11/lpctstrlptstrlpstrlpcstr.html

もし、第2引数の内容が書きかえられる可能性がある場合には、String ではなく、
StringBuilder を使う事をお薦めします。const な引数であるなら、String で良いですけど。

> 構造体*(ポインタ) I/O
> LPSTR I
# I ということは、実際には const 的な実装なのかな…。
引用返信 編集キー/
■12784 / inTopicNo.6)  Re[4]: VB.NETからVC作成DLLの関数を使用する際の引数
□投稿者/ リバー (4回)-(2008/01/17(Thu) 16:25:21)
魔界の仮面弁士さん
回答ありがとうございます。

> Pack:=8 で正しいのかどうかは、確認されましたか?
> (VC 側で、#pragma pack 指定や、pshpack1.h 等が #include されていたりはしませんね?)
>
、#pragma pack 指定、pshpack1.hの#includeはありませんでした。

> あと、DLL が Unicode コンパイルなのかどうかも確認しておいた方が良いでしょう。
> 文字列が LPWSTR や LPTSTR ではなく、LPSTR ということになると、
> CharSet.Auto では不味いかも知れませんし。

申し訳ありません。
私はVC開発の経験がないため
DLL が Unicode コンパイルかどうか判断できません。

DLL が Unicode コンパイルかどうか調べる方法をご存知でしたら
ご教授願います。

> >>第2引数は、LPCSTR ではなく、LPSTR なのですよね。
> >>であれば文字列リテラルでは無く、String 変数を指定した方が良いかも。
> DLL 側が LPSTR という点は、間違い無いのですね?
> http://www.usefullcode.net/2006/11/lpctstrlptstrlpstrlpcstr.html
>
> もし、第2引数の内容が書きかえられる可能性がある場合には、String ではなく、
> StringBuilder を使う事をお薦めします。const な引数であるなら、String で良いですけど。
>

第2引数はLPSTR型でした。
以下に入手したプログラムの一部を記載します。

extern "C" DllExport
戻り値変数 関数名( 構造体* _構造体,
LPSTR _文字列 )
{
処理
}

先ほど関数の戻り値が1:パラメータエラーでしたが
現在は、2:実行エラーになりました。
実行エラーということは引数の受け渡しについては
問題がなくなったかなと考えます。

引き続き調査を行い、実行結果が正常になりましたら
報告させていただきます。




引用返信 編集キー/
■12794 / inTopicNo.7)  Re[5]: VB.NETからVC作成DLLの関数を使用する際の引数
□投稿者/ リバー (5回)-(2008/01/17(Thu) 17:26:10)
DLLのソースコードを確認したところ
引数の受け渡しとは別の箇所でエラーが発生していることがわかりました。

別の問題は残っていますが表題の
VB.NETからVC作成DLLの関数を使用する際の引数については
解決することが出来ました。

みなさんありがとうございました。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -