2013-03-03 1 views
2

Я хотел бы вызвать функцию-член объекта .NET с использованием calli. Я могу вызвать статическую функцию, которая принимает Int и возвращает Int просто отлично используя следующий код:Использование calli для вызова функции-члена

// push the int argument 
// push the address obtained using Ldftn 
ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.StdCall, typeof<int>, [|typeof<int>|]) 
// correct result now on stack 

Я надеялся, что я мог бы использовать что-то вроде следующего вызова функции члена, который также принимает Int и возвращает int. «Программирование CIL» Джейсона Бока предполагает, что он должен работать, хотя я, вероятно, читаю его неправильно. Отражатель также считает, что что-то не совсем правильно, и утверждает, что звонок запутан. Его догадка «return (int) *ptr1(num1);», что то же самое говорит для статического вызова:

ilg.Emit (OpCodes.Ldarg_0)    
// push the int argument 
// push the address          
ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.StdCall, typeof<int>, [|typeof<int>|]) 

Когда я призываю второй фрагмент, я получаю следующее сообщение. Излишне говорить, что я не использую сортировку или что-то в этом роде.

Среда выполнения столкнулась с фатальной ошибкой. Адрес ошибки был на 0xed470d3f, на потоке 0x20e50. Код ошибки: 0xc0000005. Эта ошибка может быть ошибкой в ​​CLR или в небезопасных или не поддающихся проверке частях кода пользователя. К общим источникам этой ошибки относятся пользователи ошибки маршалинга для COM-interop или PInvoke, которые могут привести к повреждению стека .

Что я делаю неправильно, пожалуйста?

ответ

1

Согласно the documentation for calli, перегрузка EmitCalli(), которую вы используете, следует использовать только для вызова неуправляемого кода. Для управляемого кода, вы должны вызвать перегрузку, которая принимает еще один параметр и установить его в null (если вы не используете varagrg, что крайне редко):

ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.HasThis, typeof<int>, [|typeof<int>|], null) 
+0

Большое спасибо. На самом деле второй аргумент имеет другой тип в этой перегрузке, но это работает: EmitCalli (OpCodes.Calli, System.Reflection.CallingConventions.HasThis, typeof , [| typeof |], null) – user2129056

+0

@ user2129056 Право, исправлено. – svick

 Смежные вопросы

  • Нет связанных вопросов^_^