我遇到了这个错误,我不知道如何解决。这是我的代码(下面有更多详细信息):
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 的部分文档。即使它是旧的(比如从 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,只需将其重新路由到您定义的另一个函数即可。
我试图在测试项目中使用您的代码,但我不想设置为在某个独立的地方调用回调。
亲切的问候
附注我想用低质量标记您的问题。因为有文档可供阅读/谷歌和学习。您应该慢慢来,并非常友好地将您最近四个问题的一些答案标记为正确答案。
关于c++ - 错误 : 'a pointer to member is not valid for a managed class' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48825846/