c++ - 错误 : 'a pointer to member is not valid for a managed class'

标签 c++ c++-cli function-pointers

我遇到了这个错误,我不知道如何解决。这是我的代码(下面有更多详细信息):

CP1626.h

#pragma once

#include <Windows.h>
namespace CP1626{

...

//DLL functions
void setCallbackDataWriteFunc(PNIO_CBF_DATA_WRITE _ptrDataWriteFunc);

...

}

cp1626.cpp

#include "cp1626lib.h"

...

typedef void (* ptr_setCallbackDataWriteFunc)(PNIO_CBF_DATA_WRITE);
ptr_setCallbackDataWriteFunc setCallbackDataWriteFuncFunction;

...

void CP1626::setCallbackDataWriteFunc(PNIO_CBF_DATA_WRITE _ptrDataWriteFunc){
    (setCallbackDataWriteFuncFunction)(_ptrDataWriteFunc);
}

PNIO_IOXS定义为

typedef PNIO_IOXS    (*PNIO_CBF_DATA_WRITE) /* write data to IO stack (local ==> remote) */
       (PNIO_UINT32          DevHndl,       /* Handle for Multidevice */
        PNIO_DEV_ADDR      * pAddr,         /* geographical address */
        PNIO_UINT32          BufLen,        /* length of the submodule input data */
        PNIO_UINT8         * pBuffer,       /* Ptr to data buffer to write to */
        PNIO_IOXS            Iocs);         /* remote (io controller) consumer status */

然后,我使用 C++/CLI 和 .NET 编写代码,这是我的主要用户界面类,接下来由谁来完成:

UI_Main.h

#include "cp1626lib.h"

...


public ref class UI_Main : public System::Windows::Forms::Form{

    //Local function definition, which is assigned to callback
    PNIO_IOXS dataWriteFunc(PNIO_UINT32 DevHndl, PNIO_DEV_ADDR * pAddr, PNIO_UINT32 BufLen, PNIO_UINT8 * pBuffer, PNIO_IOXS Iocs);

    ...

    void InitCP1626(){
                ...

                CP1626::setCallbackDataWriteFunc(dataWriteFunc);

                ...
            }

}

错误在 CP1626::setCallbackDataWriteFunc(dataWriteFunc); 行,它表示指向成员的指针对于托管类无效。当我在托管类上时,执行此回调分配的正确形式是什么?我认为我应该找到一种方法将委托(delegate)转换为函数指针,但我对此也不确定。

提前谢谢你。

编辑:我尝试将 CP1626::setCallbackDataWriteFunc(dataWriteFunc); 行更改为 CP1626::setCallbackDataWriteFunc(Marshal::GetFunctionPointerForDelegate(del));,使用 dataWriteFunc^ del; 格式为 delegate PNIO_IOXS dataWriteFunc(PNIO_UINT32 DevHndl, PNIO_DEV_ADDR * pAddr, PNIO_UINT32 BufLen, PNIO_UINT8 * pBuffer, PNIO_IOXS Iocs);

但它也失败了。此时,错误显示“CP1626::setCallbackDataWriteFunc:无法将参数 1 从“System::IntPtr”转换为“PNIO_CBF_DATA_WRITE”

最佳答案

您可能会考虑重新阅读 Microsoft 的部分文档。即使它是旧的(比如从 2​​006 年开始),它也不会过时。

例子。 Microsoft 记录了回调的使用。 https://msdn.microsoft.com/en-us/library/367eeye0.aspx

在您的情况下,您没有查看 GetFunctionPointerForDelegate() 返回的内容。它是一个 IntPtr。这是 Microsoft 用于将所有类型的指针包装到 .NET 的一个结构中的结构。它有方法 void* ToPointer()

PNIO_CBF_DATA_WRITE cb = static_cast<PNIO_CBF_DATA_WRITE>(IntPtr.ToPointer());  
CP1626::setCallbackDataWriteFunc(cb);

请注意,您应该使用 __stdcall 进行回调。提到它是兼容性所必需的。

typedef PNIO_IOXS (__stdcall *PNIO_CBF_DATA_WRITE)

如果您无法重新编译源代码以使用 __stdcall,只需将其重新路由到您定义的另一个函数即可。

我试图在测试项目中使用您的代码,但我不想设置为在某个独立的地方调用回调。

亲切的问候

附注我想用低质量标记您的问题。因为有文档可供阅读/谷歌和学习。您应该慢慢来,并非常友好地将您最近四个问题的一些答案标记为正确答案。

关于c++ - 错误 : 'a pointer to member is not valid for a managed class' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48825846/

相关文章:

visual-c++ - 无法从 'LRESULT (__clrcall....) to ' WNDPROC' 转换

c++ - 将指向函数的指针作为参数传递给函数

rust - 特征可以作为 Fn 引用或闭包传递吗

visual-studio-2012 - 在 VS2012 中调试混合模式 C++/CLI MFC 应用程序时如何显示 native 类型

C++通过函数指针在函数内部调用 vector

c++ - 0x0040 和管道符号在这里表示什么?

c++ - 树容器迭代器接口(interface)

c++ - 如何将 GCC 诊断编译指示与 C++ 模板函数一起使用?

c++ - 在实例之间共享方法的局部静态变量有任何风险吗?

c++ - 在 C++/CLI 中包装 C 回调