VBプロジェクトから外部DLLにユーザー定義型変数を渡すには

解決


トム  2005-05-14 15:49:04  No: 89837

VBプロジェクトから外部ActiveX DLL(これも自前)にユーザー定義型変数を渡そうとしていますが、以下のエラーが出てしまいます。どうすればいいですか?教えてください。

コンパイル  エラー
「パブリック  オブジェクト  モジュールで定義されたユーザー定義型に限り、変数に割り当てることができ、実行時バインディングの関数に渡すことができます。」


魔界の仮面弁士  2005-05-14 19:15:51  No: 89838

その外部DLL上にてユーザー定義型を宣言し、それを利用してください。

Instancingプロパティを Privte以外に設定したクラスモジュール上にて
宣言されたユーザー定義型であれば、メソッドの引数等に利用できます。


トム  2005-05-15 00:10:19  No: 89839

魔界様いつもご教示ありがとうございます。

魔界様の言うとおりにチェックしてみましたが、一応DLL上でユーザー定義型を宣言しているつもりですが、まだ同じエラーが出て困っています。
対処方法を教えてください。

以下に、■DLL呼出し側/■DLL側について要所部分だけを抜粋します。

■DLL側
※Classモジュール(名称:Class1)内
    Type myStock
        Date As Date
        Open As Double
        High As Double
        Low As Double
        Close As Double
        Volume As Double
    End Type
    
Sub DrawChart(StockY() As myStock, NUM_StockY As Long)
    Dim Chart1 As Form1
    Dim i As Long
    
    For i = 1 To NUM_StockY
        StockX(i) = StockY(i)
    Next i
    'StockY():受け渡しのための変数(ユーザー定義 myStock型)
    'StockX():内部で使用のグローバル変数(ユーザー定義 myStock型)

    Set Chart1 = New Form1
    Chart1.Show
End Sub

■DLL呼出し側
    Type myStock
        Date As Date
        Open As Double
        High As Double
        Low As Double
        Close As Double
        Volume As Double
    End Type

    Public StockX(1 To 5000) As myStock
    Dim StockY(1 To 5000, 1 To 6) As Variant
    
Sub ChartDLLCall()
    Dim CHARTOBJ As Object
    Dim i As Long
    
    Set CHARTOBJ = CreateObject("Chart.Class1")

  '以下はチェックのため、データをエクセルシートから取得
    For i = 1 To 50
        StockX(i).Date = Cells(i, 1).Value
        StockX(i).Open = Cells(i, 2).Value
        StockX(i).High = Cells(i, 3).Value
        StockX(i).Low = Cells(i, 4).Value
        StockX(i).Close = Cells(i, 5).Value
        StockX(i).Volume = Cells(i, 6).Value
    Next i
    
    Call CHARTOBJ.DrawChart(StockX(), 50)
'>>>★★★                  ~~~~~~~~~ここでエラーが出ます
    
    'Set CHARTOBJ = Nothing
End Sub


魔界の仮面弁士  2005-05-15 03:23:32  No: 89840

なぜ、呼び出し側でもユーザー定義型を宣言しているのでしょうか?
定義が同じだからと言って、同じ型である事にはなりませんよ。

たとえば、DLL側でClass1を定義したとして、それと全く同じ設計の
Class1をEXE側にも定義したとしても、
  Dim A    As Project1.Class1
  Set A = New Project2.Class1
は、『型が一致しません。』のエラーになりますよね。
別々に定義してしまうと、機能的には同一であっても、
結果的には「別物」として扱われてしまいます。

だからこそ、操作対処のユーザー定義型が「公開された型」となるよう、
ActiveX DLL側で定義して、呼び出し側は、その型を利用せねば
ならないというわけです。で、それが先のエラーにある
『パブリック  オブジェクト  モジュールで定義されたユーザー定義型』
という内容に繋がってくるわけで。


トム  2005-05-15 03:53:04  No: 89841

魔界様  回答ありがとうございます。

魔界様のご指摘のように、
DLL呼出し側のmyStockはコメントアウトしましたところ、
ユーザー定義型データの受け渡しができました。

更に試しに、
   Public StockX(1 To 5000) As myStock
をコメントアウトしましたところ、
その下のStockX(i).Dateで、変数が定義されていないエラーが
出ました。

VB初心者の私には、myStockの定義をせず
  Public StockX(1 To 5000) As myStock
として使用することに抵抗があるのですが、
このmyStockは、DLLを参照設定した時点で、DLL側のユーザー定義を
参照しているのしょうか?またこれはレジストリなどと関係していますか?教えてください。


魔界の仮面弁士  2005-05-15 09:50:07  No: 89842

たとえば、Microsoft ActiveX Data Objects を参照設定すると、
  Dim RS As ADODB.Recordset
のように、「Recordsetクラス」を利用出来ます。

また、DirectX 8 for Visual Basic Type Library を参照設定すれば、
  Dim X As DIKEYBOARDSTATE
という、「DIKEYBOARDSTATE構造体」の利用が可能です。

自作のActiveX DLLも同じ事です。

DLL側で適切な記述がなされており、そして、その型情報が
タイプライブラリとしてレジストリに登録されてさえいれば、
それを参照設定する事で、DLLで公開されたクラスやユーザー定義型を
他のプロジェクトから利用する事ができるわけです。

もし、参照設定せずにレイトバインドで使いたいのであれば、
DLL側の適当なクラスに、myStock型を戻り値として返すメソッドを
用意しておけばOKです(VB6の場合)。そして呼び出し側からは、
  Dim foo As Variant
  Dim bar As Object
  Set bar = CreateObject("プロジェクト名.クラス名")
  foo = bar.test()   '←Public Function test() AS myStock
のようにしてやれば、myStockユーザー定義型がVariant型に
格納されますので、その後で、
  foo.Volume = 1.3
  Debug.Print foo.High
のようにして、参照設定無しで myStock型を利用できるかと思います。


トム  2005-05-15 14:41:52  No: 89843

魔界様  ご回答ありがとうございます。
勉強になりました。またご教授お願いいたします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加