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
> VC側ソース(XXX.DLL)
> VB2005のソース
いずれも文法的に正しく無いため、これでは判断できません。
(そもそも実行以前にコンパイルすら通らないはずなので…)
正しいコードを再掲してください。
> Redim A(49)
> Redim B(49)
この配列変数 A, B という物の説明が見当たりません。
TmpData.A() と A() は、別の配列ですよね?
> X = TmpData(0)
こんな書き方はできないハズ…。
X = TmpData.A(0) ならできるでしょうけれども。
ご指摘ありがとうございます。
以下に訂正致します。
よろしくお願い致します。
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)
> 以下に訂正致します。
コードの再掲載については、
>>> VB2005のソース
だけでなく、
>>> VC側ソース(XXX.DLL)
についてもお願いしたと思うのですが…。
> よろしくお願い致します。
配列メンバに対して、MarshalAs 属性で ByValArray を付加し、
正しい SizeConst を指定してみてください。
http://msdn2.microsoft.com/ja-jp/library/eadtsekz.aspx
ご指摘通り対応したら動きました。
ありがとうございました。
ツイート | ![]() |