[ad_1]
やあ、
先日は大変お世話になりました。
前回は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)
[ad_2]
コメント