- 001
- 002
- 003
- 004
- 005
- 006
- 007
- 008
- 009
- 010
- 011
- 012
- 013
- 014
- 015
- 016
- 017
- 018
- 019
- 020
- 021
- 022
- 023
- 024
- 025
- 026
- 027
- 028
- 029
- 030
- 031
- 032
- 033
- 034
- 035
- 036
- 037
- 038
- 039
- 040
- 041
- 042
- 043
- 044
- 045
- 046
- 047
- 048
- 049
- 050
- 051
- 052
- 053
- 054
- 055
- 056
- 057
- 058
- 059
- 060
- 061
- 062
- 063
- 064
- 065
- 066
- 067
- 068
- 069
- 070
- 071
- 072
- 073
- 074
- 075
- 076
- 077
- 078
- 079
- 080
- 081
- 082
- 083
- 084
- 085
- 086
- 087
- 088
- 089
- 090
- 091
- 092
- 093
- 094
- 095
- 096
- 097
- 098
- 099
- 100
internal unsafe static void Memcpy(byte* dest, byte* src, int len) {
Contract.Assert(len >= 0, "Negative length in memcopy!");
//
// This is portable version of memcpy. It mirrors what the hand optimized assembly versions of memcpy typically do.
//
// Ideally, we would just use the cpblk IL instruction here. Unfortunately, cpblk IL instruction is not as efficient as
// possible yet and so we have this implementation here for now.
//
switch (len)
{
case 0:
return;
case 1:
*dest = *src;
return;
case 2:
*(short *)dest = *(short *)src;
return;
case 3:
*(short *)dest = *(short *)src;
*(dest + 2) = *(src + 2);
return;
case 4:
*(int *)dest = *(int *)src;
return;
case 5:
*(int*)dest = *(int*)src;
*(dest + 4) = *(src + 4);
return;
case 6:
*(int*)dest = *(int*)src;
*(short*)(dest + 4) = *(short*)(src + 4);
return;
case 7:
*(int*)dest = *(int*)src;
*(short*)(dest + 4) = *(short*)(src + 4);
*(dest + 6) = *(src + 6);
return;
case 8:
#if WIN64
*(long*)dest = *(long*)src;
#else
*(int*)dest = *(int*)src;
*(int*)(dest + 4) = *(int*)(src + 4);
#endif
return;
case 9:
#if WIN64
*(long*)dest = *(long*)src;
#else
*(int*)dest = *(int*)src;
*(int*)(dest + 4) = *(int*)(src + 4);
#endif
*(dest + 8) = *(src + 8);
return;
case 10:
#if WIN64
*(long*)dest = *(long*)src;
#else
*(int*)dest = *(int*)src;
*(int*)(dest + 4) = *(int*)(src + 4);
#endif
*(short*)(dest + 8) = *(short*)(src + 8);
return;
case 11:
#if WIN64
*(long*)dest = *(long*)src;
#else
*(int*)dest = *(int*)src;
*(int*)(dest + 4) = *(int*)(src + 4);
#endif
*(short*)(dest + 8) = *(short*)(src + 8);
*(dest + 10) = *(src + 10);
return;
case 12:
#if WIN64
*(long*)dest = *(long*)src;
#else
*(int*)dest = *(int*)src;
*(int*)(dest + 4) = *(int*)(src + 4);
#endif
*(int*)(dest + 8) = *(int*)(src + 8);
return;
case 13:
#if WIN64
*(long*)dest = *(long*)src;
#else
*(int*)dest = *(int*)src;
*(int*)(dest + 4) = *(int*)(src + 4);
#endif
*(int*)(dest + 8) = *(int*)(src + 8);
*(dest + 12) = *(src + 12);
return;
case 14:
#if WIN64
*(long*)dest = *(long*)src;
#else
*(int*)dest = *(int*)src;
C# разрешает сказать unsafe и делать что угодно
Иначе как бы работал PInvoke (вызов нативных фукнций)?
это у них что не "деталь реализации"? и никакого моста (c-python, jni, ffi) ни промежуточного языка (perl xs) нету?
ЗЫ многие языки не мучаются и берут libFFI (foreign function interface) - она динамически умеет вызывать функции с произвольной конвенцией.
и вызывать функции из дллки (в Mono работает, в .NET Core выпилили вроде)
А еще можно взять откуда-нибудь указатель на функцию, сделать Marshal.PtrToDelegate и тоже вызвать
Соглашение вызова, кодировку и какие аргументы в какие типы конвертить - все это можно настроить
Есть вроде какой-то Ptr, но я не уверен что его всегда хватает
Для дотнетных структур надо указать [StructLayout], чтобы передавать их куда-нибудь (Sequential для упакованных структур, Explicit если надо особо выровнять)
Похоже MS много сделал чтобы уметь PInvoke out of the box.
Зы: умел бы еще структы с верным StructLayout генерить по .h файлам вообще ценыб не было
или умеет?
P.S. тем более что в юнионы (только если с костылями) и битфилды не умеет
ну вот почему?
почему для SOAP по WSDL они умеют стабы, почему по IDL обычно для RPC и COM и что там еще они тоже умеют стабы (вроде бы), а по .h нет?
я просто хотел сказать что это пахнет идиотизмом -- сидеть и переписывать вручную структуры из msdn
Дожили, люди уже ЯВНЫЙ ЗЕЛЁНЫЙ не понимают.
Если по инерции пойти дальше, вывод будет ещё страшнее: кнопка выставления рейтинга тоже зеленая!.. Неужели, во всём этом скрыт сарказм?.. Не верится, что страйко так ужасно насмеялся над всеми нами... Я считаю, всё же, что зеленый цвет - что-то вроде подсказки для тупиц, о том, что мнение голосующих не всегда объективно.
Возьмём, к примеру, борманда. Его плюсовали и за дело, и тогда, когда он постил гоатсе.
Разумеется. По умолчанию на этом сайте всё следует толковать как сарказм, пока не заявлено обратное. Зелёный цвет лишь является напоминанием.
Как Вам?
в добавок еще и ихнюю хуиту с *printf* функциями исправит.
Извините, но я больше не намерен тут оставаться с таким отношением!!