无法从' LRESULT(__ clrcall ....)转换为' WNDPROC'

时间:2012-12-27 09:59:04

标签: visual-c++ c++-cli

我尝试在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;
}

};
}

2 个答案:

答案 0 :(得分:1)

这是错误的,因为您的WndProc()函数正在编译为IL,而不是机器代码。发生这种情况是因为你使用/ clr编译它有效。它不仅仅是编译时错误,它也无法在运行时运行。 Windows不知道如何调用托管方法,而不是没有从Marshal :: GetFunctionPointerForDelegate()获得的帮助。

最好不去那里。将此代码移动到您在没有/ clr选项的情况下编译的单独.cpp文件中。或者在此代码之前使用#pragma managed(push, off),以便将其编译为机器代码而不是IL。

并考虑托管类包装器,它们为您提供相同类型的功能。与System.Windows.Forms命名空间中的类一样。或者,如果你想保留这段代码,那么从NativeWindow类派生你自己的类来附加窗口句柄,允许你用托管代码覆盖WndProc()。

答案 1 :(得分:0)

显然,托管类的方法不支持__stdcall调用约定。因此,您需要将WindowProc放在非托管类中:

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

ref class Win32Demo
{
    ...
};

一个建议:打开警告,以便收到有关此类内容的警告。有了警告,您就会收到以下警告:

  

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