- PR -

VB6.0 と VC++6.0 の連携

1
投稿者投稿内容
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-10-17 15:12
今、C 言語で作成された関数を VC++6.0 に移行して DLL化し、その DLL を VB6.0 で利用しようと考えております。

VC++ は初めてですので、検索しながら試行錯誤しているのですが、連携部分でつまずいておりますので、お力をお貸し下さい。

単純なサンプルを作成して試しているのですが、

VC++6.0 側
コード:
extern "C" __declspec (dllexport) int __stdcall Test1(int X, int Y);
extern "C" __declspec (dllexport) int __stdcall Test1(int X, int Y)
{
	return X+Y;
}


VB6.0 側
コード:
Private Declare Function Test1 Lib "Crypt.dll" (ByVal x As Long, _
                                                ByVal y As Long) As Long

Private Sub Command1_Click()
    Dim ret As Long

    ret = Test1(5, 4)
    Label1.Caption = ret
End Sub


は、正常に動作したのですが、文字列の連携が出来なくて悩んでおります。

VC++6.0 側
コード:
extern "C" __declspec (dllexport) int __stdcall Test2(char *X, char *Y);
extern "C" __declspec (dllexport) int __stdcall Test2(char *X, char *Y)
{
	Y[0] = 'A';
	Y[1] = 'Z';
	Y[2] = '@';
	return 0;
}


VB6.0 側
コード:
Private Declare Function Test2 Lib "Crypt.dll" (ByRef x As String, _
                                                ByRef y As String) As Long
Private Sub Command1_Click()
    Dim ret As Long
    Dim strKekka As String * 3

    ret = Test2("123", strKekka)
    Label1.Caption = strKekka
End Sub


で実行すると、メモリエラーで VB6.0 の EXE が異常終了します。

http://www6.ocn.ne.jp/~hoshiya/VCTips.html

などを参考にすると、文字列の連携は難しいようなのですが、返り値ではなく、引数でうまく VB 側で VC++ がセットした値を取得できないのでしょうか?
想馬
大ベテラン
会議室デビュー日: 2003/05/29
投稿数: 245
お住まい・勤務地: 神奈川・東京
投稿日時: 2006-10-17 15:29
やったこと無いので予想ですが・・・
コード:
Dim strKekka As String * 3


コード:
Dim strKekka As String * 4

としてY[3]に'¥0'をセットするとどうでしょうか?

# ¥は半角にしてください
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-10-17 15:59
想馬さん、こんにちは。

引用:

想馬さんの書き込み (2006-10-17 15:29) より:

やったこと無いので予想ですが・・・
コード:
Dim strKekka As String * 3


コード:
Dim strKekka As String * 4

としてY[3]に'¥0'をセットするとどうでしょうか?

# ¥は半角にしてください




終端文字ですね。やってみましたが、結果は変わらず、でした。
ぷさいくろう
ぬし
会議室デビュー日: 2006/08/30
投稿数: 1034
投稿日時: 2006-10-17 16:13
>ret = Test2("123", strKekka)

こんな呼び方してるからでは
アドレスなし子ちゃん
ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-10-17 16:34
ぷさいくろうさん、こんにちは。

引用:

ぷさいくろうさんの書き込み (2006-10-17 16:13) より:

>ret = Test2("123", strKekka)

こんな呼び方してるからでは
アドレスなし子ちゃん



呼び出し方が違いますか?

http://support.microsoft.com/default.aspx?scid=kb;ja;410837#XSLTH3161121122120121120120

なんかを参考にして、VB 側からは「ByRef」(参照渡し)で渡せばいいのかな、と考えていますが。
だーやん
会議室デビュー日: 2004/03/07
投稿数: 16
投稿日時: 2006-10-17 16:36
ByValではどうでしょう?


http://www.gogomonkey.2y.net/prog/useAPI_fromVB.html
特に注意する必要があるのは、DLLに文字列を渡すときには ByVal つまり値渡しで渡すことです。こうしておくと VB は、文字列へのポインタ(変数の先頭アドレス)を DLL に渡してくれます。また、VB と DLL の値の受け渡しの際、自動的に Unicode → ANSI(VB がDLLに値を渡す時), ANSI → Unicode(DLLがVBに値を渡す時) 変換を行ってくれる仕様になっています。

ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-10-17 16:56
だーやんさん、こんにちは。

引用:

だーやんさんの書き込み (2006-10-17 16:36) より:

ByValではどうでしょう?


http://www.gogomonkey.2y.net/prog/useAPI_fromVB.html
特に注意する必要があるのは、DLLに文字列を渡すときには ByVal つまり値渡しで渡すことです。こうしておくと VB は、文字列へのポインタ(変数の先頭アドレス)を DLL に渡してくれます。また、VB と DLL の値の受け渡しの際、自動的に Unicode → ANSI(VB がDLLに値を渡す時), ANSI → Unicode(DLLがVBに値を渡す時) 変換を行ってくれる仕様になっています。



だーやんさんのおっしゃる通り、「ByVal」でうまくいきました。
ありがとうございます。

上記のような仕様だったんですね。
ぷさいくろうさんもこの事を指摘してくれていたんですね。気付かずに、すいませんでした。

私が最初にリンクしたページでは、VC++ 側でポインタで受け取っているものは、「ByVal」を付けていませんでしたので、てっきり「ByRef」(既定値)が正しいものだと思っておりました。

助かりました。ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)