-2

com interop に取り組んでいる間、このリンクのチュートリアルに従いました。要件に応じていくつかの変更を行ったため、コードは正常に動作しますが、文字列の処理中に問題が発生します。ここでは境界として BSTR 文字列を使用しています。ここに私がC++から呼び出しているC#の関数があります

  public  string ShowDialog([MarshalAs(UnmanagedType.BStr)] string stringToPrint)
    {
      //  Console.WriteLine(" Enter TOTP input:");
       // stringToPrint = Console.ReadLine();

        if (stringToPrint == "111111")
        {

            MessageBox.Show("true");



        }
        else
        {
            MessageBox.Show("false");

        }

        return stringToPrint;
    }

ここに、呼び出しが行われているコードの C++ メイン関数セクションがあります

CoInitialize(NULL);

MyInterop::IMyDotNetInterfacePtr pDotNetCOMPtr;

HRESULT hRes = pDotNetCOMPtr.CreateInstance(MyInterop::CLSID_MyDotNetClass);
if (hRes == S_OK)
{

    BSTR lResult ;

    cout << "enter TOTP input" << endl;

    _bstr_t bstrStatus = SysAllocString(L"111111");

    pDotNetCOMPtr->ShowDialog(bstrStatus,&lResult);

    SysFreeString(bstrStatus);


}

CoUninitialize();

system("pause");

ここに出力があります ここに画像の説明を入力

私が直面している問題は次のとおりです。

  • C# で戻り関数を使用しているにもかかわらず、C++ コードから渡された後、BSTR 文字列がコンソールに返されない
  • ここでSysAllocString("")を使用しているため、コンソールに動的に入力を挿入することは可能ですか?
4

1 に答える 1

0

Visual Studio と #import ディレクティブを使用している場合、生成されたコードは、 BSTR (生の Windows 型)のスマート ラッパー クラスである_bstr_tを使用します。

したがって、SysAllocString や SysFreeString を使用する必要はなく、_bstr_t を非常に自然に使用できます。たとえば、あなたの場合、C# メソッドの署名が次のようになっているとします。

public string ShowDialog(string stringToPrint) // you don't need the MarshalAs here, the TLB will build it as a BSTR

次に、次のような C++ コードを使用できます。

... other imports or includes
// import mscorlib so we have a full generated cool code (I recommend not to use raw_interfaces_only)
// we rename 'or' to something that doesn't pose problems. Your mileage can vary depending on your building context...
#import "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb" rename("or","whatever")
#import "C:\myPath\MyClassLibrary1.tlb" // adapt to your path

int main()
{
  CoInitialize(NULL);
  {
    MyClassLibrary1::_Class1Ptr ptr;
    HRESULT hr = ptr.CreateInstance(__uuidof(MyClassLibrary1::Class1)); // should return S_OK/0

    _bstr_t input = L"111111";
    _bstr_t res = ptr->ShowDialog(input); // assign the return string
    wprintf(L"res:%s\n", res.GetBSTR()); // output (unicode) result to console
  }
  CoUninitialize();
}

これを直接書くこともできます:

_bstr_t res = ptr->ShowDialog(L"111111");

// または this (ANSI から Unicode への自動変換を使用)

_bstr_t res = ptr->ShowDialog("111111");

すべての _bstr_t は自動的に割り当てられ、解放されます。

于 2019-01-09T15:05:26.137 に答える