【解決方法】【.net】VBでマーシャリングされた構造体をBSTR構造体としてVC++に渡す方法を知りたいです。


やあ、

先日は大変お世話になりました。

前回はBSTR構造体で出力してVBに渡す方法で行き詰まりましたが、今回はVBからVC++へ入力として渡す方法で行き詰まりました。
前回とは逆のことをやろうと思ったのですが、未熟だったせいか、なかなかうまくいきませんでした…。

<やりたいこと>

VB でマーシャリングされた構造体を BSTR 構造体として VC++ に渡す方法を知りたいです。

VB(画面/FORM):構造(MarshalAs(UnmanagedType.Bstr)

VC++(DLL):typedef(BSTR)

<開発環境>
Windows7(32bit)
VisualStudio2008(VB/VC++)

<実行環境>
Windows7(32ビット)

ありがとうございました。

私が試したこと:

以前の解決策を参考に以下のソースコードを試してみましたが、VC++側でBstr構造体を参照するとエラーが発生しました。

VB側の「tpNonPosDet2」構造体を引数として関数を呼び出し、VC++側の「NPOS_DETAIL_UPD2」構造体としてデータを受け取りたい。

【esql_com.h】

C++
typedef struct {
	BSTR	szFunctionFlag;
	BSTR	szServiceNo;
	BSTR	szPosNo;
	BSTR	szSeqNo;
	BSTR	szCreateDate;
	BSTR	szCreateTime;
	BSTR	szSalMoney;
	BSTR	szRiyuCode;
	BSTR	szServiceRank;
	BSTR	szServiceRankAdd;
	BSTR	szServiceTime;
	BSTR	szChangeTime;
	BSTR	szTantoCode;
	BSTR	szCustKubn;
	BSTR	szKozaNo;
	BSTR	szKozaType;
} NPOS_DETAIL_UPD2;



__declspec(dllexport) int __stdcall Esql_UpNonPos(PS_HEADER_UPD *lpHeader, long *nIndexNum, NPOS_DETAIL_UPD2 *lpDetail);

【esql_com.sc】

C++
// I used SAFEARRAY in VC++6.0, but I can't find a method that works well in VC++9.0, so I used another method.
//__declspec(dllexport) int __stdcall Esql_UpNonPos
//                           (PS_HEADER_UPD *lpHeader, long *nIndexNum, LPSAFEARRAY *lpDetail)
__declspec(dllexport) int __stdcall Esql_UpNonPos
                           (PS_HEADER_UPD *lpHeader, long *nIndexNum, NPOS_DETAIL_UPD2 *lpDetail)
{
	long	lCount=0;
	int		ii;
	int		nSqlstate;                   // SQL Return Code
	char	*work;                       // WorkArea
	PS_HEADER_UPD		wk_Header;       // Header Information
	NPOS_DETAIL_UPD		wk_Detail;       // Detail Information
	long				iRet;            // Return Code
	NPOS_DETAIL_UPD2	npos;				// For structure reference
//	LPSAFEARRAY			psa = *lpDetail;	// For structure reference
	int					idx[1], lb, ub;		// For structure reference
	static char			bufa[1024];			// For structure reference
	static wchar_t		bufw[1024];			// For structure reference
	static size_t		st;					// Work Area
	static char     	mbs[256];           // Test Area For MessageBox


//*****************************************************************************
//	Processing start setting
//*****************************************************************************

	EXEC SQL WHENEVER SQLERROR  GOTO :SQL_ERROR;

	EXEC SQL SET TRANSACTION READ WRITE;

//*****************************************************************************
//	SQL
//*****************************************************************************
  	MessageBox( NULL, TEXT("Esql_UpNonPos"), TEXT("Esql_com.sc"), MB_OK);
  	MessageBox( NULL, TEXT(lpHeader->szServiceNo), TEXT("Esql_com.sc"), MB_OK);



//	Setting for structure reference
//================================
	setlocale(LC_ALL,"Japanese");
//	SafeArrayLock(psa);
//	SafeArrayGetLBound(psa, 1, &lb);
//	SafeArrayGetUBound(psa, 1, &ub);
//	idx[0] = lb;
	idx[0] = 0;



//	Setting for detail information
//================================
	EXEC SQL WHENEVER NOT FOUND CONTINUE;
	for(ii=0; ii<*nIndexNum; ii++) {
		// I used SAFEARRAY in VC++6.0, but I can't find a method that works well in VC++9.0, so I used another method.
//		SafeArrayGetElement(psa, &idx[0], &npos);
		npos = lpDetail[idx[0]];    //←I get an error here. 

		// Reference of processing flag [add/delete etc] (obtained from argument structure)
		MessageBox( NULL, TEXT(" 0.1  START"), TEXT("Esql_UpNonPos"), MB_OK);
		*bufa = 0x00;
		wcsncpy_s(bufw, 1024, npos.szFunctionFlag, 2);
		wcstombs_s(&st, NULL,     0,  &bufw, 1024);
		wcstombs_s(&st, &bufa[0], st, &bufw, 1024);
		memset(wk_Detail.szFunctionFlag, '\0', sizeof(wk_Detail.szFunctionFlag));
		strncpy_s(wk_Detail.szFunctionFlag, sizeof(wk_Detail.szFunctionFlag), bufa, 2-1);
		MessageBox( NULL, TEXT(" 0.1  END"), TEXT("Esql_UpNonPos"), MB_OK);
		MessageBox( NULL, TEXT(wk_Detail.szFunctionFlag), TEXT("Esql_UpNonPos Structure  1"), MB_OK);
・
・
・

【API_Refer.vb】

VB
<DllImport("Esql_DLL.dll", CharSet:=CharSet.Ansi)> _
Public Function Esql_UpNonPos(<[In]()> ByVal Up_dtpPSHead As tpPS_Hed2, ByRef RecordCnt As Long, <[In]()> ByVal Up_dtpNonPosDet() As tpNonPosDet2) As Integer
End Function

【mdlPkSrv.vb】

VB
 <StructLayout(LayoutKind.Sequential)> _
 Structure tpNonPosDet2
     <MarshalAs(UnmanagedType.BStr)> Dim strShoriFlg As String
     <MarshalAs(UnmanagedType.BStr)> Dim strSrvNo As String
     <MarshalAs(UnmanagedType.BStr)> Dim strPosNo As String
     <MarshalAs(UnmanagedType.BStr)> Dim strTuuban As String
     <MarshalAs(UnmanagedType.BStr)> Dim strToriDate As String
     <MarshalAs(UnmanagedType.BStr)> Dim strToriTime As String
     <MarshalAs(UnmanagedType.BStr)> Dim strKingaku As String
     <MarshalAs(UnmanagedType.BStr)> Dim strRiyuCd As String
     <MarshalAs(UnmanagedType.BStr)> Dim strSrvRank As String
     <MarshalAs(UnmanagedType.BStr)> Dim strAddSrvRank As String
     <MarshalAs(UnmanagedType.BStr)> Dim strSrvTime As String
     <MarshalAs(UnmanagedType.BStr)> Dim strChgTime As String
     <MarshalAs(UnmanagedType.BStr)> Dim strHanbaiinCd As String
     <MarshalAs(UnmanagedType.BStr)> Dim strCostomKbn As String
     <MarshalAs(UnmanagedType.BStr)> Dim strKozaNo As String
     <MarshalAs(UnmanagedType.BStr)> Dim strKozaSbh As String
End Structure

【元PkSrv1.vb】

VB
Ret = Esql_UpNonPos(dtp_GotHedData, RecordCnt, dtp_NonPosDet)

コメント

タイトルとURLをコピーしました