0

既存の VS2008 ベースの C++/CLI プロジェクト (具体的には CefSharp) を VS2012 にアップグレードしていますが、その間にいくつかの課題に直面しています。コンパイルで VS2008 に依存することを避けるために、.NET Framework 4.0 を対象とするようにプロジェクトをアップグレードしました。

すべて問題なく、プロジェクトは正しくコンパイルされますが、実行して WebView インスタンスを作成しようとすると、次の TypeLoadException が発生します。

アセンブリ 'CefSharp.Wpf、Version=1.25.0.35385、Culture=neutral、PublicKeyToken=null' のタイプ 'CefSharp.Wpf.WebView' のメソッド 'SetCursor' には実装がありません。":"CefSharp.Wpf.WebView"

明らかに、私は WebView.h と WebView.cpp の両方をかなり詳しく調べました。それらの内容は(関連部分)です:

public ref class WebView sealed : public ContentControl, IRenderWebBrowser
{
public:
    virtual void SetCursor(CefCursorHandle cursor);
}

そして実装:

void WebView::SetCursor(CefCursorHandle cursor)
{
    SafeFileHandle^ handle = gcnew SafeFileHandle((IntPtr)cursor, false);
    Dispatcher->BeginInvoke(DispatcherPriority::Render,
        gcnew Action<SafeFileHandle^>(this, &WebView::SetCursor), handle);
}

CefCursorHandle は次のように定義されます。

#define CefCursorHandle cef_cursor_handle_t

...そして cef_cursor_handle_t は次のように定義されます:

#define cef_cursor_handle_t HCURSOR

つまり、windef.h 構造体です。

インターフェイス(IRenderWebBrowser)ところで。このようにメソッドを定義します。

public interface class IRenderWebBrowser : IWebBrowser
{
public:
    void SetCursor(CefCursorHandle cursor);
}

ある時点で、この問題は「const」と「non-const」の問題に関連していると思いましたが、例に見られるように、関連する const 指定子はありません。:-(

ここで見逃している明らかな落とし穴は何ですか? この投稿をざっと読みましたが、実際には役に立ちませんでした。

また、アセンブリの複数の/古いバージョンがどこかにぶら下がっている可能性についても考えたので、正しいバージョンがロードされていることを確認するためにアセンブリバージョンをバンプしようとしました-それはそうでした. また、アセンブリで ILSpy を調べたところ、メソッドは確実に存在します。ただし、そのメソッド シグネチャは次のとおりです。

public unsafe void SetCursor(HICON__* cursor)

安全でない部分、またはそのパラメーター (HICON__*) が C#/CLR コンテキストからアクセスできないという事実に関連している可能性がありますか? (私は C# アセンブリから型をインスタンス化しようとしています。) C++/CLI はまだ私の専門分野ではないことを認めなければなりません... :-)

誰?

(誰かが詳細を詳しく調べたい場合は、https://github.com/perlun/CefSharp/で自由にプロジェクトを複製/調査してください。これは vs2012 ブランチにあります。)

4

2 に答える 2

0

これが他の誰かの役に立てば幸いです... どうやら私の疑いは正しかったようです。型はアンマネージ(およびマネージ ワールドにアクセスできない) ため、C++ コンパイラは、WebView が宣言されているアセンブリ内の内部CLR 構造体として CefCursorHandle/HICON 構造体を作成します。これにより、メソッドは本質的に呼び出し不可になり (内部パラメーターを持つパブリック メソッド => C# から呼び出すことができなくなります)、型が C# からインスタンス化されようとすると、CLR はこれについてバーフするように見えます...

パラメーターの型をIntPtrに変更すると、コードが意図したとおりに機能するようになりました。「void *」もオプションで、C++ 側で使用する方が簡単な場合があります。

(これらのケースでは、C#/マネージ側でメソッドを使用する必要がないため、IntPtr/void * を使用するだけで問題ありません。実際に使用されている場合は、適切なマーシャリングがこれよりも優れたアイデアになります。 )

于 2013-05-01T19:49:21.073 に答える
0

フォローアップ: 実験のために、C# で IRenderWebBrowser インターフェイスを実装しようとしました。

public unsafe class Foo : IRenderWebBrowser
{
    public void SetBuffer(int width, int height, void* buffer)
    {
        throw new NotImplementedException();
    }

    // ...and so forth.
}

これを (/unsafe フラグを有効にした後に) コンパイルすると、これを引き起こしている (可能性のある) 原因についてより多くの洞察が得られます。

1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(167,31,167,38): error CS0122: 'HICON__' is inaccessible due to its protection level
1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(167,21,167,30): error CS0051: Inconsistent accessibility: parameter type 'HICON__*' is less accessible than method 'CefSharp.Wpf.Example.Foo.SetCursor(HICON__*)'
1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(182,45,182,52): error CS0122: 'CefRect' is inaccessible due to its protection level
1>Y:\git\ataranto.CefSharp\CefSharp.Wpf.Example\MainWindow.xaml.cs(182,21,182,44): error CS0051: Inconsistent accessibility: parameter type 'CefRect*' is less accessible than method 'CefSharp.Wpf.Example.Foo.SetPopupSizeAndPosition(CefRect*)'

HICON__ が C#/マネージ ワールドにアクセスできない場合、これらのメソッドが型に存在するという事実により、控えめに言っても CLR が少し「混乱」し、マネージド コンテキストから型をインスタンス化できなくなる可能性が十分にあります。C++/CLI でメソッドを公開する (問題のインターフェイスを実装する) ことを指定する方法はありますか?

于 2013-05-01T18:05:37.540 に答える