|
■No84659 (myzk さん) に返信 > CONNECT3(VARIANT * RecvData)が正しい形でした。byrefの&は付いていませんでした。 > 度々の誤表記でご迷惑をお掛けして申し訳ありません。
DLL 側で V_VT(RecvData) が VT_BYREF | VT_BSTR となるよう、 VARIANT 構造体の内容を調整してみました。
// void WINAPI CONNECT(VARIANT * RecvData); [DllImport("HelloWorld.dll")] private static extern void CONNECT(IntPtr RecvData);
// WINOLEAUTAPI_(void) VariantInit(__out VARIANTARG * pvarg); [DllImport("oleaut32")] private static extern void VariantInit(IntPtr pVariant);
// WINOLEAUTAPI VariantClear(__inout VARIANTARG * pvarg); [DllImport("oleaut32", PreserveSig = true)] private static extern void VariantClear(IntPtr pVariant);
static void Main() { string str = "Hello World";
// Variant の作成 IntPtr pVariant = Marshal.AllocCoTaskMem(8 + 2 * IntPtr.Size); VariantInit(pVariant); Marshal.GetNativeVariantForObject(str, pVariant);
// VT_BSTR から VT_BYREF | VT_BSTR へと変更 Marshal.WriteInt16(pVariant, 0, (short)(VarEnum.VT_BYREF | VarEnum.VT_BSTR)); //IntPtr bstrVal = Marshal.StringToBSTR(str); IntPtr bstrVal = Marshal.ReadIntPtr(pVariant, 8); // BSTR の取得 IntPtr pbstrVal = Marshal.AllocCoTaskMem(IntPtr.Size); Marshal.WriteIntPtr(pbstrVal, 0, bstrVal); Marshal.WriteIntPtr(pVariant, 8, pbstrVal); // BSTR* に書き換え
// ターゲットの呼び出し CONNECT(pVariant);
// 使うかどうかは分からないけれど、念のため // VARIANT の内容をマネージ側に戻しておく object resultObject = Marshal.GetObjectForNativeVariant(pVariant); string resultString = resultObject as string;
// Variant の解放 VariantClear(pVariant); Marshal.FreeBSTR(bstrVal); Marshal.FreeCoTaskMem(pVariant); Marshal.FreeCoTaskMem(pbstrVal); }
|