У меня есть функция следующий C++ (принадлежит к COM-интерфейс, полученный от IUnknown), который я хочу позвонить из C# код:доступа исключение нарушения при вызове функции в Си ++ из C#
декларации C++ как документировано:
HRESULT Function1([in] STRUCT1 *s1, [in, out] STRUCT2 *s2, [in] SIZE_T var1);
Декларация внутри рабочей C++ программе:
STDMETHOD(Function1)(
THIS_
__out STRUCT1 * s1,
__in_ecount_opt(var1) const STRUCT2 * s2,
SIZE_T var1
) PURE;
В # территории C определяю следующие:
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT1
{
public uint member1; //HRESULT member1
public ulong member2; //SIZE_T member2
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT2
{
public IntPtr member1; //VOID *member1;
public ulong member2; //SIZE_T member2;
public STRUCT3 member3; //STRUCT3 member3;
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT3
{
public int member1; //int member1
}
Я реализовать эту функцию в C# следующим образом:
[ComImport, ComVisible(false), InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("…")]
public interface Iinterface1
{
……
uint Function1(ref STRUCT1 s1, ref STRUCT2 s2, ulong var1);
……
}
и я вызвать функцию так:
STRUCT1 temp1 = new STRUCT1();
temp1.member1 = 0;
temp1.member2 = 0;
STRUCT2 temp2 = new STRUCT2();
STRUCT3 temp3 = new STRUCT3();
temp3.member1 = 0;
temp2.member1 = IntPtr.Zero;
temp2.member2 = 0;
temp2.member3 = temp3;
ulong var1 = 1;
res1 = COMobject.Function1(ref temp1, ref temp2, var1);
При выполнении функции я получаю нарушение прав доступа Исключение:
«Необработанное исключение типа« System.AccessViolationException »произошло в prog1.exe Дополнительная информация: Попытка чтения или записи защищенной памяти. Это часто свидетельствует о том, что другая память повреждена. "
Я реализовал большинство функций одного и того же интерфейса без проблем, а также множество других интерфейсов в этом приложении. Это меня действительно озадачивает.
Я очень ценю вашу помощь по этому ..
Спасибо заранее.
Вы можете посмотреть на http://manski.net/2012/06/pinvoke-tutorial-pinning-part-4/ –
Вы должны использовать '' IntPtr' для SIZE_T' (необходимо только если он может работать на 32-битном процессоре, но в любом случае хорошая практика). Я также предлагаю вам дважды проверить, выполняется ли AccessViolationException в коде маршалинга или из самого метода com. –
@Brian: Спасибо за ваши предложения.Можете ли вы предложить лучший способ удвоить проверку, если это происходит в процессе сортировки или в методе com? Я нацелен только на 64 бит, а исходный код метода com недоступен. – spsk