C# 如何修复';无法封送';返回值';:无效的托管/非托管类型组合(Int/UInt必须与SysInt或SysUInt成对出现);
我试图从C++的C++回调中返回一个结构,我得到了标题中描述的错误。 我很感激有很多信息,但我想包括太多而不是不够 我已经尝试过将函数作为结构返回,但是阅读后,将函数作为IntPtr返回并使用Marshal.PtrtoStructure可能会更容易 我要调用的函数来自不同来源的.dll,输入为: C++:C# 如何修复';无法封送';返回值';:无效的托管/非托管类型组合(Int/UInt必须与SysInt或SysUInt成对出现);,c#,c++,struct,pinvoke,dllimport,C#,C++,Struct,Pinvoke,Dllimport,我试图从C++的C++回调中返回一个结构,我得到了标题中描述的错误。 我很感激有很多信息,但我想包括太多而不是不够 我已经尝试过将函数作为结构返回,但是阅读后,将函数作为IntPtr返回并使用Marshal.PtrtoStructure可能会更容易 我要调用的函数来自不同来源的.dll,输入为: C++: rVDACQ\u Connect(int、tVDACQ\u CallBackProc、void*、short*、int) 示例(C++代码)中的函数返回一个结构(rACQ_CallBackR
rVDACQ\u Connect(int、tVDACQ\u CallBackProc、void*、short*、int)
示例(C++代码)中的函数返回一个结构(rACQ_CallBackRec),如下所示:
typedef struct {
int rFlags, // combination of cVDACQ_Fxxxx
rType, // cVDACQ_ETxxx
rEvent, // cVDACQ_Exxx
rSocket; // 0:no relation to a 'socket'; otherwise socket's ID>0 (event's source ID)
TCHAR rMsg[256]; // message (trace, wrn, err)
int rFrameWidth, // full frame width
rFrameHeight; // full frame height
short* rFrameBuffer; // user supplied frame buffer "AFrameBuffer"
union {
int rCaptureRows; // # of received rows (for single frame acquisition)
int rCaptureFrames; // # of received full frames (for framegrabber)
};
int rCapturePercent; // received data in percents
void* rUserCallBackProc, // user supplied "ACallBackProc"
* rUserParam; // user supplied "AUserParam"
int rAborted; // 1: VDACQ_Abort -1:internally
void* rPacketData; // pointer to received packet; usually it is nil
int rFGControl; // frame-grabber's control flags
} tVDACQ_CallBackRec;
typedef void(_stdcall* tVDACQ_CallBackProc)(tVDACQ_CallBackRec*); //The Callback
rACQ\u CallBackRec=theApp.m\u Intf.rVDACQ\u Connect(cVDACQ\u FBright,CALLBACK\u Acquisition,this,m\u FrmBuffer,0);
//rACQ_CallBackRec是结构类型tvdaq_CallBackRec(如下所述)
其回收量为:
extern“C”{
__declspec(dllexport)void_stdcall CALLBACK_Acquisition(tvdaq_CallBackRec*AR)
{
TVDAQ_回调过程测试;
((CPreviewDlg*)AR->rUserParam->My_ACQ_回调(AR,测试);
}
}
结构的布局如下所示:
typedef struct {
int rFlags, // combination of cVDACQ_Fxxxx
rType, // cVDACQ_ETxxx
rEvent, // cVDACQ_Exxx
rSocket; // 0:no relation to a 'socket'; otherwise socket's ID>0 (event's source ID)
TCHAR rMsg[256]; // message (trace, wrn, err)
int rFrameWidth, // full frame width
rFrameHeight; // full frame height
short* rFrameBuffer; // user supplied frame buffer "AFrameBuffer"
union {
int rCaptureRows; // # of received rows (for single frame acquisition)
int rCaptureFrames; // # of received full frames (for framegrabber)
};
int rCapturePercent; // received data in percents
void* rUserCallBackProc, // user supplied "ACallBackProc"
* rUserParam; // user supplied "AUserParam"
int rAborted; // 1: VDACQ_Abort -1:internally
void* rPacketData; // pointer to received packet; usually it is nil
int rFGControl; // frame-grabber's control flags
} tVDACQ_CallBackRec;
typedef void(_stdcall* tVDACQ_CallBackProc)(tVDACQ_CallBackRec*); //The Callback
C#
我在C#中创建了回调过程,以及struct和PInvoke:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
公共代表无效TVDAQ_CallBackProc(TVDAQ_CallBackRec AR);
[DllImport(“C:\\Users\\jch\\source\\repos\\FlatPanelSensor\\x64\\Debug\\VADAV\u AcqS.dll”,EntryPoint=“CALLBACK\u Acquisition”,CallingConvention=CallingConvention.Cdecl)]
公共不安全静态外部无效回调采集(tVDACQ\U回调REC AR);
[DllImport(“C:\\Users\\jch\\source\\repos\\FlatPanelSensor\\FlatPanelSensor\\bin\\Debug\\VADAV\u FGM\u 64.dll”,EntryPoint=“VDACQ\u Connect”,CallingConvention=CallingConvention.Cdecl)]
[返回:Marshallas(UnmanagedType.I4)]
公共不安全静态外部IntPtr VDACQ_Connect(inti[marshallas(UnmanagedType.FunctionPtr)]tVDACQ_CallBackProc proc,dynamic n,IntPtr[]buffer,intj);
结构:
[StructLayout(LayoutKind.Sequential)]
public struct tVDACQ_CallBackRec
{
public int rFlags;
public int rType;
public int rEvent;
public int rSocket;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string rMsg;
public int rFrameWidth;
public int rFrameHeight;
public IntPtr rFrameBuffer;
public int rCaptureRows;
public int rCaptureFrames;
public int rCapturePercent;
public IntPtr rUserCallBackProc;
public IntPtr rUserParam;
public int rAborted;
public IntPtr rPacketData;
public int rFGControl;
}
回拨:
tVDACQ_CallBackProc callBack =
(AR) =>
{
CALLBACK_Acquisition(AR); //Don't know how necessary this
is
};
函数调用:
IntPtr work = VDACQ_Connect(0, callBack, this, m_FrmBuffer, 0);
//I know 'this' isn't defined as a void* in my DLLImport,
//but making it an IntPtr didn't work either so
//the only type I could think of was dynamic.
如果我可以将其作为IntPtr返回,或者更好地返回我在C#代码中定义的结构,那就太好了
如果您需要更多信息,请告诉我,因为我想我包括了所有信息。与
VDACQ\u Connect
相同吗?在代码中RVDACQUnLink的返回类型(您错过了C++签名)是什么,它们定义了函数,就像在加载库时返回类型是TealTVTdACQQCalBeReCr,我也把它作为C++代码的一部分。希望这能帮助我知道您是否还需要其他内容,或者我是否遗漏了其他内容。因此,如果它返回TVDAQ_CallBackRec,为什么您的P/Invoke签名会让它返回IntPtr
?因为我在某个地方(不记得在哪里)读到可以作为IntPtr返回的内容,然后使用Marshal.PtrToStructure。然而,我试着以TVDAQ_CallBackRec和IntPtr的身份返回。当我使用TVDAQ_CallBackRec作为返回类型时,我得到了“方法的类型签名与P/Invoke不兼容”,我认为这是结构有问题的地方很多问题。TCHAR可以是ansi或unicode,在C#中进行选择。TVDAQ_CallBackRec AR参数应标记为ref
。您应该从VDACQ\U Connect中删除[返回:marshallas(UnmanagedType.I4)]
,以与IntPtr保持一致。你不应该需要不安全的。根本不要使用FunctionPtr。通过IntPtr n
更改dynamic n
IntPtr[]buffer
可以,但这取决于C的期望值和传递给它的内容。rVDACQ\u Connect
与VDACQ\u Connect
相同吗?在代码中RVDACQUnLink的返回类型(您错过了C++签名)是什么,它们定义了函数,就像在加载库时返回类型是TealTVTdACQQCalBeReCr,我也把它作为C++代码的一部分。希望这能帮助我知道您是否还需要其他内容,或者我是否遗漏了其他内容。因此,如果它返回TVDAQ_CallBackRec,为什么您的P/Invoke签名会让它返回IntPtr
?因为我在某个地方(不记得在哪里)读到可以作为IntPtr返回的内容,然后使用Marshal.PtrToStructure。然而,我试着以TVDAQ_CallBackRec和IntPtr的身份返回。当我使用TVDAQ_CallBackRec作为返回类型时,我得到了“方法的类型签名与P/Invoke不兼容”,我认为这是结构有问题的地方很多问题。TCHAR可以是ansi或unicode,在C#中进行选择。TVDAQ_CallBackRec AR参数应标记为ref
。您应该从VDACQ\U Connect中删除[返回:marshallas(UnmanagedType.I4)]
,以与IntPtr保持一致。你不应该需要不安全的。根本不要使用FunctionPtr。通过IntPtr n
更改dynamic n
IntPtr[]buffer
可能还可以,但这取决于C的期望值和传递给它的内容。