VB2005からVCのDLLから値を取得するためには

解決


ひよこPG  2008-02-07 08:24:17  No: 144397

VB6からVB2005にバージョンアップをしました。VCで作成したDLLの関数はそのまま使用したのですが下記エラーが出てしまい値を取得できません。

エラー内容
「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。」

いろいろサイト等を調べたのですがうまくいきません。
Marshal.AllocCoTaskMem、Marshal.Copyなどを使用すればできるらしいのですがうまくいかず。。。
配列変数ではなく配列の数だけ変数を定義した場合は取得はできてます。数が多く現実的ではないですが。。

どなたかご教授下さい。
よろしくお願い致します。

VC側ソース(XXX.DLL)

GetData(
  unsigned char far          *pRec,       //データ
  short int      *pRecLen,   //サイズ
{
  Char    cbBuf[1024];  //バッファ

  memset(cbBuf, ' ', 1024);  //初期化
  
  Call GetBuf(cbBuf);

   memcpy(pRec, cbBuf, *pRecLen);

  return(0) ;
}

VB2005のソース

    <StructLayout(LayoutKind.Sequential)> Structure St
          Dim A () As Byte 
          Dim B () As Byte 
    End Structure

    Declare Function GetData Lib "XXX.DLL" (Byref RecData As St , ByRef Reclen As Short) As Short

Sub
    Dim TmpData As St
    Dim TmpLen As short =100
    Dim X As Byte
    Dim Y As Byte

    Redim A(49)
    Redim B(49)

    Call GetData(TmpData, TmpLen)

    X =TmpData(0)
    Y =TmpData(1)
         ・
         ・
End Sub


魔界の仮面弁士  2008-02-07 18:32:14  No: 144398

> VC側ソース(XXX.DLL)
> VB2005のソース
いずれも文法的に正しく無いため、これでは判断できません。
(そもそも実行以前にコンパイルすら通らないはずなので…)

正しいコードを再掲してください。

>    Redim A(49)
>    Redim B(49)
この配列変数 A, B という物の説明が見当たりません。
TmpData.A() と A() は、別の配列ですよね?

> X = TmpData(0)
こんな書き方はできないハズ…。
X = TmpData.A(0) ならできるでしょうけれども。


ひよこPG  2008-02-07 21:39:32  No: 144399

ご指摘ありがとうございます。
以下に訂正致します。
よろしくお願い致します。

Redim A(49)→Redim TmpData.A(49) 
Redim B(49)→Redim TmpData.B(49)

X =TmpData(0) →  X =TmpData.A(0)
Y =TmpData(1) →  Y =TmpData.A(1)


魔界の仮面弁士  2008-02-08 00:57:20  No: 144400

> 以下に訂正致します。
コードの再掲載については、
>>> VB2005のソース
だけでなく、
>>> VC側ソース(XXX.DLL)
についてもお願いしたと思うのですが…。

> よろしくお願い致します。
配列メンバに対して、MarshalAs 属性で ByValArray を付加し、
正しい SizeConst を指定してみてください。
http://msdn2.microsoft.com/ja-jp/library/eadtsekz.aspx


ひよこPG  2008-02-08 10:55:47  No: 144401

ご指摘通り対応したら動きました。
ありがとうございました。


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




  


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