3

VS 2010 でマネージド C++ アセンブリを作成して、WinAPI とやり取りし、それを他の C# アセンブリで使用しようとしています。GitHub でコードを検索しても、すべての投稿を読みましたが、成功しませんでした。エラー メッセージの __clrcall に関するものかもしれませんが、__stdcall ではないでしょうか。何か案は?

正確なエラー メッセージは次のとおりです。

エラー C2440: '=': 'LRESULT (__clrcall xxx::Win32Demo::* )(HWND,UINT,WPARAM,LPARAM)' から 'WNDPROC' に変換できません

ソースコード:

#pragma once

using namespace System;
using namespace System::Drawing;

#include "stdafx.h"
#include "windows.h"

namespace xxx
{

ref class Win32Demo
{

private: HWND__ * handle;
private: static Char * windowClass;

public:

Win32Demo(void)
{
}

static Win32Demo()
{
    tagWNDCLASSEXW w;
    windowClass = (wchar_t*) L"Hello";

    w.cbSize = sizeof(tagWNDCLASSEXW);
    w.style = 0x803;
    w.lpfnWndProc = WindowProc; // Error
    w.cbClsExtra = 0;
    w.cbWndExtra = 0;
    w.hInstance = 0;
    w.hIcon = 0;
    w.hCursor = 0;
    w.hbrBackground = CreateSolidBrush(0);
    w.lpszMenuName = NULL;
    w.lpszClassName = windowClass;
    w.hIconSm = 0;
}

public :
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return 0;
}

};
}
4

2 に答える 2

2

WndProc() 関数がマシン コードではなく IL にコンパイルされているため、これはうまくいきません。これは、/clr を有効にしてコンパイルしたために発生しました。これは単なるコンパイル時エラーではなく、実行時にも機能しません。Windows は、Marshal::GetFunctionPointerForDelegate() から得られるような支援なしではなく、マネージ メソッドを呼び出す方法を知りません。

そこには行かないほうがいいです。/clr オプションを指定せずにコンパイルする別の .cpp ファイルにこのコードを移動します。または#pragma managed(push, off)、IL ではなくマシン コードにコンパイルされるように、このコードの前に使用します。

また、同じ種類の機能を提供するマネージ クラス ラッパーを検討してください。System.Windows.Forms 名前空間のクラスと同様です。または、このコードを保持したい場合は、NativeWindow クラスから独自のクラスを派生させてウィンドウ ハンドルをアタッチし、マネージ コードで WndProc() をオーバーライドできるようにします。

于 2012-12-27T15:22:42.437 に答える
0

どうやら __stdcall 呼び出し規約はマネージド クラスのメソッドではサポートされていません。したがって、アンマネージ クラス内に WindowProc を配置する必要があります。

class WindowProcCallback
{
public:
    static LRESULT __stdcall WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        ...
    }
};

ref class Win32Demo
{
    ...
};

1 つの提案: 警告をオンにして、このようなものに関する警告が表示されるようにします。警告があれば、次の警告が表示されます。

warning C4441: calling convention of '__stdcall ' ignored; '__clrcall ' used instead

于 2012-12-27T14:15:31.743 に答える