Я уже давно борюсь с этой проблемой и надеюсь, что кто-нибудь может помочь.Я конвертирую приложение VB6 в C #.Все, что я собираюсь показать, прекрасно работает в VB6, но терпит неудачу в C #.
Я делаю вызов API в Cll, передавая структуру.Структура получает значения, измененные на стороне C, и я должен увидеть измененные значения в моей структуре возврата.
Обратите внимание, Sig - это int, Status - это int, а CLIENTID - это UINT_PTR.
Вот структуры C:
typedef struct
{
short vers;
short flags;
short cmd;
short objtype;
DWORD id;
DWORD client;
char buf[MAX_TOOLBUF];
DWORD toolID;
NMSG msg;
DWORD caller;
CLIENTID clientID;
DWORD ticket;
ToolResult PTR result;
long spare[4];
} Request;
typedef struct
{
DWORD hwnd;
DWORD message;
DWORD wParam;
DWORD lParam;
} NMSG;
typedef struct
{
Sig sig;
short cnt;
Status error;
DWORD ticket;
DWORD toolID;
long spare[4];
} ToolResult;
В моем коде C # у меня есть следующие структуры, определенные для отображения на структуры C выше:
[StructLayout(LayoutKind.Sequential)]
public struct NMSG
{
public int hWnd;
public int msg;
public int wParam;
public int lParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct Request
{
public Int16 vers;
public Int16 flags;
public Int16 cmd;
public int16 objType;
public int id;
public int Client;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string buf;
public int toolID;
public NMSG msg;
public int caller;
public IntPtr clientID;
public int ticket;
public ToolResult result;
[MarshalAs(UnmanagedType.ByValArray, SizeConst= 4) ]
public int64[] spare;
}
Это декорация метода вкод C:
SendRequest(Request PTR req)
{
....
}
Вот мое объявление PInvoke в C # для API в C, который использует эти структуры:
[DllImport("TheCDLL.dll", EntryPoint = "_Request@4", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void Request(ref Request req);
А вот мой код C #, который заполняет структуру иделает вызов API:
Request req = new Request();
req.vers = 1;
req.toolID = 4000;
req.Client = 0;
req.cmd = 11;
req.objType = 1;;
req.id = 1;
req.msg.hWnd = Hwnd; // verified this is a valid window handle
req.msg.msg = 1327;
req.msg.wParam = 101;
req.msg.lParam = 0;
req.spare = new int[4];
req.buf = new string(' ', 260);
req.flags = 11;
Request(ref req);
Проблема в том, что в коде VB6 элемент структуры 'result' заполняется значением после того, как я сделаю вызов API.В C # 'result' всегда равно 0. Я предполагаю, что у меня что-то не так с тем, как я собираюсь?Я прочитал десятки статей и попробовал много разных способов, чтобы это работало безуспешно.Любая помощь приветствуется!
ОБНОВЛЕНИЕ: Теперь, когда я обновил код на основе приведенных ниже предложений (исправление типов и очистка кода в том виде, в котором оно было написано изначально), я получаю исключение:
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Я обнаружил, что это происходит, как только я изменил «public int16 vers» с «public int vers» в моей структуре запросов.Мысли?