2009-08-13 59 views
14

C++/CLIポインタをネイティブC++ポインタに変換するこの問題を実行しました。 Heres the background: 私はC++/CLIを使ってWindowsフォームアプリケーションを書いています。アプリケーションは、いくつかのCOMインターフェイスを呼び出します。 COMインターフェイスを介してオブジェクトの(C++/CLRクラスの内側)のインスタンスを作成する場合、私は同様に、CoCreateInstanceの最後の引数として(void**)(&provider)渡し:C++/CLIポインタからネイティブC++ポインタへの変換

HRESULT CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, (void**)(&provider)); 

しかし、私は、コンパイラエラーが発生します。 cli::interior_ptr<Type>からvoid **に変換できません。 私はこれについてsomの研究を行っており、C++とC++/CLIではさまざまな種類のポインタの問題のようです。誰もがこれについて何か知識を持っていて、それがどうやって修正できるかについてのヒントを教えてくれますか?あらかじめThanx!

まず、すべてのあなたの助けを借りて!

Freichが提案したように、pin_ptrを使用しようとしましたが、代わりにinterior_ptrからpin_ptrに変換する問題についてコンパイラが不平を言っていました。私が代わりのようにinterior_ptrを使用しようとすると:

pin_ptr<void *> pinnedPtr = &provider; 
CoCreateInstance(CLSID_MSPRProvider, NULL, CLSCTX_LOCAL_SERVER, IID_IMSPRProvider, (void**)pinnedPtr); 

私はinterior_ptrからinterior_ptrに変換することはできません取得します。 interior_ptrvoid**に変換するという問題はすべて解決します。このように:(void**)interiorPtr、ここでinteriorPtrinterior_ptrです。この中の任意のアイデア?

答えて

10

私は、(マネージコードで) '固定'としてマークし、次にいくつかの管理されていないメモリ領域にバイトをコピーして、そのポインタを使用する必要があると思います。私が手に持ってどのように

std::string managedStringToStlString(System::String ^s) 
{ 
    Encoding ^u8 = Encoding::UTF8; 
    array<unsigned char> ^bytes = u8->GetBytes(s); 
    pin_ptr<unsigned char> pinnedPtr = &bytes[0]; 
    return string((char*)pinnedPtr); 
} 

注:たとえば、ここではUTF-8でエンコードされた管理対象外のstd ::文字列に管理対象システム::文字列へのポインタを変換し、私は一度どこかになったコードの一部です配列bytesに返されたポインタをGetBytes()関数によって返された後、char*にキャストしてからstd::stringコンストラクタに渡します。これは、管理されたメモリサブシステムが、STL文字列にバイトをコピーしている間にメモリ内のbytes配列を移動させないようにするために必要だと思います。

は、あなたのケースでは、

pin_ptr<void *> pinnedPtr = &provider; 
CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, (void**)pinnedPtr); 

CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, (void**)(&provider)); 

を交換してみてください、それが動作するかどうかを確認します。

+0

これは危険です!私は前と同じような状況がありました。固定ポインタを作成してネイティブポインタを返しましたが、関数が終了し固定ポインタが削除されたためオブジェクトが移動されたため、オブジェクトはもはや存在しませんでした固定されていて、ネイティブポインタが無効でした!これはデバッグ中に表示されても、表示されなくてもかまいませんが、期待していないときはリリースバージョンで確実に発生します。 –

+0

@TobiasKnauss 'std :: string :: string(const char *)'コンストラクタは、参照されるデータのコピーを作成するので、関数が終了するときに参照先のメモリが固定されなくなっても問題ありません。 –

3

私はC++/CLIを使っていたのですが、ポインタを固定する必要があると思います。

+0

CLIと呼ばれる便利なテンプレートがあります::あることを確実にするために設計されていますようOPは必要なものかもしれませんpin_ptr管理対象オブジェクトへのポインタは、ガベージコレクタによって移動されていません。 –

3

CoCreateInstance()の呼び出し以外に有効と予想されるメモリはありますか?

FrerichとAchimが指摘しているように、メモリを再配置することを心配することなく、メモリを「固定」して内部ポインタを取得することで、メモリへの生ポインタを得ることができます。通常は、これをpin_ptrテンプレートで行います(例についてはFrerich postを参照してください)。

ただし、pin_ptrは故意にスタック上でのみ使用できます。メンバー変数またはグローバル変数として使用することはできません。引数または戻り値として渡すことはできません。スコープを離れるとメモリは固定解除されます。

したがって、メモリがCoCreateInstance()の呼び出し中に有効である必要がある場合は、pin_ptrを使用します。 ない場合、あなたはメモリのコピーを取るとのCoCreateInstance(上へことを渡す必要があります)