Пытаясь вернуть структуру с точным макетом, как в C++, проблема заключается в том, что TCHAR rMsg[256]
включен в структуру C++, а [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public char rMsg;
включен в структуру C# (оба будут показаны ниже). Я получаю сообщение об ошибке "Тип метода несовместим с PInvoke" .
Я также должен указать, что C++ не мой, и я не могу его изменить, поскольку для других функций требуется макет структуры, приведенный ниже.
Я знаю, что проблема в TCHAR, поскольку, когда я комментирую соответствующие строки в C++ и C#, я не получаю ошибку.
Я вызываю созданную мной .dll (которую я также включу в приведенный ниже код) только для того, чтобы вернуть структуру, чтобы знать, что у меня правильный синтаксис.
C++:
extern "C" {
__declspec(dllexport) tVDACQ_CallBackRecVal ( _stdcall TestAcq2())
{
//Just adding random values so I know it works.
tVDACQ_CallBackRecVal AR;
AR.rFlags = 1;
AR.rFrameHeight = 10;
AR.rFrameWidth = 10;
return AR;
}
}
//Struct
typedef struct {
int rFlags,
rType,
rEvent,
rSocket;
TCHAR rMsg[256]; //Has to stay as TCHAR
int rFrameWidth,
rFrameHeight;
short* rFrameBuffer;
union {
int rCaptureRows;
int rCaptureFrames;
};
int rCapturePercent;
void* rUserCallBackProc,
* rUserParam;
int rAborted;
void* rPacketData;
int rFGControl;
} tVDACQ_CallBackRecVal;
C#:
//Simply calling the .dll
[DllImport("C:\\Users\\jch\\source\\repos\\FlatPanelSensor\\x64\\Debug\\VADAV_AcqS.dll", EntryPoint = "TestAcq2", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern tVDACQ_CallBackRec TestAcq2();
[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; //I believe this is the issue
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;
}
//Then I just call the function
tVDACQ_CallBackRec testStruct= TestAcq2();
Я бы ожидал, что структура имеет все компоненты, как определено, но вместо этого я получаю сообщение об ошибке, как указано в заголовке.
Опять же, если бы я не включал TCHAR (структура С++) и строку (структура С#), я бы не получил ошибку, поэтому я знаю, что это основная проблема, и я не знаю, как решить эту часть.
РЕДАКТИРОВАТЬ: для решения см. Первый комментарий от @David Heffernan
void _stdcall TestAcq2(tVDACQ_CallBackRecVal* retval)
- person David Heffernan   schedule 31.10.2019