错误:'指向成员的指针对托管类无效'

时间:2018-02-16 11:31:11

标签: 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);行,它表示指向成员的指针对托管类无效。当我在托管类上时,执行此回调分配的正确形式是什么?我认为我应该找到一种方法将委托转换为函数指针,但我也不确定。

提前谢谢。

编辑:我尝试使用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''

1 个答案:

答案 0 :(得分:1)

您可能会考虑重新阅读Microsoft的部分文档。即使它已经过时(如2006年),它也不会过时。

实施例。 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,只需将其重新路由到您定义的另一个函数。

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

亲切的问候

P.S。我想以低质量标记你的问题。因为有文档可供阅读/谷歌和学习。你应该花时间和善意在最近的四个问题上标出一些答案作为正确的答案。