[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2006/12/21(Thu) 15:43
投稿者名:茄子茄子
Eメール:
URL :
タイトル:
[[解決]]VB6.0でのバイナリデータの渡し方について
はじめまして、首記の件について皆様のお知恵を借りたく投稿致します。

実装したい処理:
 VC#.NETで作成したCOMインターフェイスのメソッド呼び出し
(メソッドの引数としてバイト配列を取る)
発生事象:
 「コンパイルエラー
 関数またはインターフェイスが予約されているか、またはVisual Basicでサポートされていない
 オートメーションタイプが関数で使用されています。」と表示され、下記☆部分のメソッドが反転
 表示されます。

質問1:
 VB6.0で他コンポーネント呼び出しを行う際にバイト配列を指定することは可能かどうか?
質問2:
 上記エラーのVisulaBasicでサポートされていないートメーションタイプが関数で使用されています。
 ↑
 はTLBの参照登録がうまく行っていないということでしょうか?

 該当COMのTLBファイル生成、RegAsm、プロジェクトへの参照の追加時はこれといって
 エラーメッセージみたいなものも出ず、正常に参照が追加されたと思っていたのですが、、、

Private Sub Command41_Click()

Dim HogeIF As HogeHogeDLL.IHogehoge //COMのオブジェクト変数宣言

Set HogeIF = New HogeHogeDLL.Hogehoge
Dim ByteArr() As Byte
ReDim ByteArr(15) As Byte

For i = 0 To 15
ByteArr(i) = i  //0〜15の代入
Next
Call HogeIF.HogeMethod(ByteArr) // バイト配列を引数とするメソッド・・・☆

HogeIF = Nothing

投稿時間:2006/12/21(Thu) 19:15
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: VB6.0でのバイナリデータの渡し方について
> Call HogeIF.HogeMethod(ByteArr) // バイト配列を引数とするメソッド・・・☆

「'」では無く「//」になっている所に苦笑い…。(^-^;


> メソッドの引数としてバイト配列を取る

COM メソッドの引数定義が『ByRef foo() As Byte』になっていますか?
VB6 は、『ByVal foo() As Byte』を処理できませんので。


とりあえず、サンプルという事で。

# あえてゴテゴテと属性を付けまくってみる。
---------
using System;
using System.Runtime.InteropServices;

namespace HogeHogeDLL
{
    /// <summary/>
    [Guid("F902FEDF-8146-469a-BF2E-FF03596F2901")]
    public interface IHogehoge
    {
        void HogeMethod(
            [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
            ref byte[] array);
    }

    /// <summary>ほげほげ</summary>
    [Guid("D3C4768C-E007-4029-9D21-DF5A77C53E29")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("HogeHogeDLL.Hogehoge.1")]
    public class Hogehoge : IHogehoge
    {
        /// <summary>配列の各要素を、それぞれ倍の値にします。</summary>
        /// <param name="array">byteの1次元配列</param>
        public void HogeMethod(ref byte[] array)
        {
            if (array == null)
            {
                array = new byte[0];
            }
            for (int i = 0; i < array.Length; i++)
            {
                unchecked { array[i] *= 2; }
            }
        }
    }
}

投稿時間:2006/12/25(Mon) 09:41
投稿者名:茄子茄子
Eメール:
URL :
タイトル:
Re^2: VB6.0でのバイナリデータの渡し方について
レスありがとうございます。
返信が遅れまして申し訳ありません。


> COM メソッドの引数定義が『ByRef foo() As Byte』になっていますか?
> VB6 は、『ByVal foo() As Byte』を処理できませんので。
↑の件、値渡し:○ 、参照渡し:×ということでしょうか?
WEB、参考書等見ながら現象の調査をしてみます。

> > Call HogeIF.HogeMethod(ByteArr) // バイト配列を引数とするメソッド・・・☆
>
> 「'」では無く「//」になっている所に苦笑い…。(^-^;
>
>
> > メソッドの引数としてバイト配列を取る
>
> COM メソッドの引数定義が『ByRef foo() As Byte』になっていますか?
> VB6 は、『ByVal foo() As Byte』を処理できませんので。
>
>
> とりあえず、サンプルという事で。
>
> # あえてゴテゴテと属性を付けまくってみる。
> ---------
> using System;
> using System.Runtime.InteropServices;
>
> namespace HogeHogeDLL
> {
>     /// <summary/>
>     [Guid("F902FEDF-8146-469a-BF2E-FF03596F2901")]
>     public interface IHogehoge
>     {
>         void HogeMethod(
>             [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
>             ref byte[] array);
>     }
>
>     /// <summary>ほげほげ</summary>
>     [Guid("D3C4768C-E007-4029-9D21-DF5A77C53E29")]
>     [ComVisible(true)]
>     [ClassInterface(ClassInterfaceType.None)]
>     [ProgId("HogeHogeDLL.Hogehoge.1")]
>     public class Hogehoge : IHogehoge
>     {
>         /// <summary>配列の各要素を、それぞれ倍の値にします。</summary>
>         /// <param name="array">byteの1次元配列</param>
>         public void HogeMethod(ref byte[] array)
>         {
>             if (array == null)
>             {
>                 array = new byte[0];
>             }
>             for (int i = 0; i < array.Length; i++)
>             {
>                 unchecked { array[i] *= 2; }
>             }
>         }
>     }
> }

投稿時間:2006/12/25(Mon) 13:10
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3: VB6.0でのバイナリデータの渡し方について
# 引用は適切に。

> > COM メソッドの引数定義が『ByRef foo() As Byte』になっていますか?
> > VB6 は、『ByVal foo() As Byte』を処理できませんので。
> ↑の件、値渡し:○ 、参照渡し:×ということでしょうか?

……違います。というか逆です。

言語仕様上、VB6 は『ByVal(値渡し)』を「処理できない」のですが、
『ByRef(参照渡し)』ならば OK である、という意味の回答をしています。
(どうしてもVB6で配列を値渡ししたいなら、「Variant型」を経由させる必要があります)

投稿時間:2006/12/25(Mon) 13:20
投稿者名:茄子茄子
Eメール:
URL :
タイトル:
Re^4: VB6.0でのバイナリデータの渡し方について
たびたびのレスありがとうございます。

> # 引用は適切に。
申し訳ありません、気をつけます。

> 言語仕様上、VB6 は『ByVal(値渡し)』を「処理できない」のですが、
> 『ByRef(参照渡し)』ならば OK である、という意味の回答をしています。
> (どうしてもVB6で配列を値渡ししたいなら、「Variant型」を経由させる必要があります)
↑も含めて、レスして頂いたサンプルを参考にしつつ引き続き勉強します。
2、3日中に、プログラム修正を行い、結果をお伝えできればと考えております。
年末作業でパンパンでして、、、(汗)
自分でやってみてどうしても分からない事があれば、引き続きご助力いただければと思います。


> # 引用は適切に。
>
> > > COM メソッドの引数定義が『ByRef foo() As Byte』になっていますか?
> > > VB6 は、『ByVal foo() As Byte』を処理できませんので。
> > ↑の件、値渡し:○ 、参照渡し:×ということでしょうか?
>
> ……違います。というか逆です。
>
> 言語仕様上、VB6 は『ByVal(値渡し)』を「処理できない」のですが、
> 『ByRef(参照渡し)』ならば OK である、という意味の回答をしています。
> (どうしてもVB6で配列を値渡ししたいなら、「Variant型」を経由させる必要があります)

投稿時間:2006/12/25(Mon) 17:05
投稿者名:茄子茄子
Eメール:
URL :
タイトル:
Re^4: VB6.0でのバイナリデータの渡し方について
ありがとうございます。
参照渡しのでのメソッド呼び出し、無事実装することが出来ました。

COM側のソースを確認したところ、下記のようにHogeMethodのインターフェイス部、
実装部ともに、ref指定がされていませんでした。
☆1、☆2にrefを追加し、明示的に参照渡しをするように記述したところ、
参照を渡すことが出来ました。

追加質問です。
.NETでは、refの指定を行わない場合、値渡しとなるという記述を見つけたのですが、
バイト配列の【値渡し】での関数呼び出しは可能なのでしょうか?
(VC#.NETのドライバから値渡しにて、該当のメソッドを呼び出すことは可能でした。)

Variant バイト配列 値渡しなどのキーワードを元に、探してみたのですが、
これだ!というものが見つからず、、、
勉強をする際のキーワード、参考ページ等ございましたら、教えて頂きたく。
宜しくお願い致します。


     [Guid("F902FEDF-8146-469a-BF2E-FF03596F2901")]
     public interface IHogehoge
     {
         void HogeMethod(
             byte[] array);// ☆1
     }

     /// <summaryほげほげ</summary
     [Guid("D3C4768C-E007-4029-9D21-DF5A77C53E29")]
     public class Hogehoge : IHogehoge
     {
         public void HogeMethod(byte[] array) //☆2
         {
        /*
            略
        */
         }
     }

投稿時間:2006/12/25(Mon) 20:11
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^5: VB6.0でのバイナリデータの渡し方について
VB6 側の話を主体にするなら、ここの掲示板で良いですが、
C#.NET の話をしたいのであれば、C# 向けの掲示板を利用してくださいね。


> .NETでは、refの指定を行わない場合、値渡しとなるという記述を見つけたのですが、
.NET 対応の言語は何種類もありますので、『.NET では』というと語弊があるような。

で、その記述というのは、「C#.NET同士」でやりとりする場合の話でしょうか。
それとも、「COM とのマーシャリング」の際の話なのでしょうか?


> バイト配列の【値渡し】での関数呼び出しは可能なのでしょうか?
.NET 側では、方向属性(InAttribute/OutAttribute)での制御が可能かと思いますが、
VB6 側が、配列を直接値渡しするタイプライブラリを直接処理できないかと思います。

VB6 側で参照設定せず、内部の関数を直接呼び出せば利用できるとは思いますが、
面倒なだけですから、素直に COM 側の定義を VB6 向けに書き直すべきでしょう。


> (VC#.NETのドライバから値渡しにて、該当のメソッドを呼び出すことは可能でした。)
ドライバとは?


> Variant バイト配列 値渡しなどのキーワードを元に、探してみたのですが、
VB6 では、
 Sub Sample1(ByVal S As Variant)
というメソッドに対して、
  Dim B() As Byte
  ReDim B(3)
  B(0) = 11
  B(1) = 22
  B(2) = 33
  B(3) = 44
  Call Sample1(B)
という処理が可能だという事です。

下記も参考にしてみてください。
http://support.microsoft.com/kb/317030/ja

投稿時間:2006/12/26(Tue) 11:36
投稿者名:茄子茄子
Eメール:
URL :
タイトル:
Re^6: VB6.0でのバイナリデータの渡し方について
>VB6 側の話を主体にするなら、ここの掲示板で良いですが、
>C#.NET の話をしたいのであれば、C# 向けの掲示板を利用してくださいね。
すみません。発生していた問題を解決する為にVB6.0側で何をしなければいけないのか
という観点で質問させて頂きましたが。
結論としてはCOM側で参照渡しに設定しなければ、COMとして利用する場合は、VB6.0の言語仕様上
利用できないということですね。

>.NET 対応の言語は何種類もありますので、『.NET では』というと語弊があるような。
>で、その記述というのは、「C#.NET同士」でやりとりする場合の話でしょうか。
>それとも、「COM とのマーシャリング」の際の話なのでしょうか?
その掲示板では.NETという括りでしか述べられていませんでしたが、COMとのマーシャリング
の話だと思います。COMの属性指定をしなければ規定では値渡しになる〜等記載されていました。

>ドライバとは?
.NET2003のVB,VC#にてCOMを参照し、値渡しによる呼び出しを実行しましたがそちらでは可能だった
ということを説明したかったのですが、説明不足でした。

>VB6 側で参照設定せず、内部の関数を直接呼び出せば利用できるとは思いますが、
>面倒なだけですから、素直に COM 側の定義を VB6 向けに書き直すべきでしょう。
参照設定をしないということはCOMとして利用しないということでしょうか?


値渡しの件に関しては引き続き勉強したいと思います。値渡し、参照渡し両方出来るようになりたく、
まだまだ勉強不足です。

魔界の仮面弁士さん、
スレ違いな質問にも親切に答えて下さり、大変感謝致します。
ありがとうございました。

投稿時間:2006/12/26(Tue) 12:23
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^7: VB6.0でのバイナリデータの渡し方について
> 結論としてはCOM側で参照渡しに設定しなければ、COMとして利用する場合は、VB6.0の言語仕様上
> 利用できないということですね。
VB6 では、「ユーザー定義型」と「配列型」は、参照渡しが必要とされます。
それ以外の「整数型」「文字列型」「日付型」などは、値渡しでも参照渡しでも OK です。

ただし、VB6 で認識不可能な型(Signed Byte、Unsigned 32bit Integer など)は、
参照渡し/値渡しに関係なく、利用することができません、ということで。

>> VB6 側で参照設定せず、内部の関数を直接呼び出せば利用できるとは思いますが、
>> 面倒なだけですから、素直に COM 側の定義を VB6 向けに書き直すべきでしょう。
> 参照設定をしないということはCOMとして利用しないということでしょうか?
COM としては利用はしますが、VB6 の標準機能を用いてアクセスするのではなく、
COM API 等を直接呼び出すことによって、より低レベルな処理を行うという話です。

> スレ違いな質問にも親切に答えて下さり、大変感謝致します。
多少板違いな部分はありましたが、スレ違いという事は無かったと思いますよ。