- 締切済み
VB2005でVC6.0で作成したDLLから値を取得するには
VB6からVB2005にコンバートをしたのですがVCで作成したDLLの関数の箇所で下記エラーが出てしまいました。(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 TmpData.A(49) Redim TmpData.B(49) Call GetData(TmpData, TmpLen) X =TmpData.A(0) Y =TmpData.B(1) ・ ・ End Sub
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- redfox63
- ベストアンサー率71% (1325/1856)
別の方法としては 単純なByte配列として渡してやれば出来そうです VB2005側で declare Function GetData( ByVal buf() as byte, ByRef nLen as short) as Short と宣言します データを ByValの配列で宣言するのがミソです Dim buf(99) as Byte, status as short, nn as short = 100 status = GetData( buf, nn ) といった具合です … この後必要なら構造体に代入しましょう
- redfox63
- ベストアンサー率71% (1325/1856)
このコードでは無理があるでしょう 元のVCのコードは VB6側で固定長配列で定義されたユーザー定義型を渡すことを前提にされたコードです VB6側を動的配列として定義 Private Type St A() as Byte B() as Byte End Type declare Function GetData lib "xxx.dll" _ (byRef dat as St, ByRef n as Intger) as Integer Sub Test() dim obj as St, nn as integer nn = 100 Redim St.A(49) Redim St.B(49) GetData( st, nn ) End Sub といった具合に変更すると例外が発生します これと同等のことを VB2005でしているのです VB2005とVB6で共通のDLLでやるならDLL側をSafeArrayでアクセスするように変更しないといけません 構造体の定義を struct _tagSt { LPSAFEARRAY psa; // tmpData.A LPSAFEARRAY psb; // tmpData.B }; と定義します __declspec( dllexport ) short __stdcall GetData2( struct _tagSt* parm, short* pn ) { int cdim, lbound, ubound, n; char* buf = NULL; buf = (char*)malloc( *pn ); GetBuf( buf, *pn ); // 配列の次元数を取得 cdim = SafeArrayGetDim( parm->psa ); // 配列の添え字範囲を取得 SafeArrayGetLBound( pram->psa, &cdim, &lbound ); SafeArrayGetUBound( pram->psa, &cdim, &ubound ); for ( n = lbounf; n < ubound + 1; n++ ) { // 配列要素の更新 SafeArrayPutElement( pram->psa, &n, &buf[n] ); } cdim = SafeArrayGetDim( parm->psb ); SafeArrayGetLBound( pram->psb, &cdim, &lbound ); SafeArrayGetUBound( pram->psb, &cdim, &ubound ); for ( n = lbounf; n < ubound + 1; n++ ) { SafeArrayPutElement( pram->psb, &n, &buf[n+50] ); } // 確保したメモリーの破棄 free( buf ); return 0; } といった具合にして見ましょう