Если список является большим, работающий самым высоким образом способ сделать, это должно будет использовать генератор:
def get_chunk(iterable, chunk_size):
result = []
for item in iterable:
result.append(item)
if len(result) == chunk_size:
yield tuple(result)
result = []
if len(result) > 0:
yield tuple(result)
for x in get_chunk([1,2,3,4,5,6,7,8,9,10], 3):
print x
(1, 2, 3)
(4, 5, 6)
(7, 8, 9)
(10,)
Взгляните на раздел «В памяти» этой статьи. Поймите, что это с точки зрения удаленной инъекции DLL, но концепция должна быть такой же.
Создание RAM-диска или сброс кода в память с последующим его выполнением - оба возможных, но чрезвычайно сложных решения (возможно, в большей степени в управляемом коде).
Должен ли он быть исполняемым файлом ? Если вы упаковываете его как сборку, вы можете использовать Assembly.Load () из потока памяти - пару тривиальных строк кода.
Или, если это действительно должен быть исполняемый файл, что на самом деле не так с записью временного файла ? Потребуется несколько строк кода, чтобы выгрузить его во временный файл, выполнить его, дождаться его выхода, а затем удалить временный файл - он может даже не выйти из кеша диска, прежде чем вы его удалите! Иногда простое и очевидное решение оказывается лучшим решением.
Вы просите реализовать очень низкоуровневую, зависящую от платформы функцию в управляемой среде высокого уровня. Все возможно ... но никто не сказал, что это будет легко ...
(Кстати, я не знаю, почему вы считаете, что управление временными файлами обременительно. BCL делает это за вас: http: // msdn .microsoft.com / en-us / library / system.io.path.gettempfilename.aspx )
Выделите достаточно памяти для хранения исполняемого файла. Конечно, он не может находиться в управляемой куче, поэтому, как и почти все в этом упражнении, вам понадобится PInvoke. (На самом деле, я рекомендую C ++ / CLI, чтобы не свести себя с ума). Обратите особое внимание на биты атрибутов, которые вы применяете к выделенным страницам памяти: сделайте их неправильно, и вы ' либо откроет зияющую дыру в безопасности, либо ваш процесс будет остановлен DEP (т. е. произойдет сбой). См. http://msdn.microsoft.com/en-us/library/aa366553 (VS.85) .aspx
Найдите исполняемый файл в библиотеке ресурсов сборки и получите закрепленный дескриптор к нему.
Memcpy () код из закрепленной области управляемой кучи в собственный блок.
Освободите GCHandle.
Вызовите VirtualProtect , чтобы предотвратить дальнейшую запись в исполняемую память блок.
Вычислить адрес функции Main исполняемого файла в виртуальном адресном пространстве вашего процесса на основе дескриптора, полученного от VirtualAlloc, и смещения в файле, как показано DUMPBIN или аналогичными инструментами.
Поместите нужную команду строковые аргументы в стеке. ( Соглашение Windows Stdcall ). Разумеется, любые указатели должны указывать на собственные или закрепленные области.
Переход к вычисленному адресу. Вероятно, проще всего использовать _call (встроенный язык ассемблера).
Молитесь Богу, чтобы в исполняемом образе не было никаких абсолютных переходов, которые можно было бы исправить, вызвав LoadLibrary обычным способом. (Если, конечно, вы не захотите заново реализовать логику LoadLibrary на шаге №3.)
Получить возвращаемое значение из регистра @eax.
Вызвать VirtualFree.
Шаги №5 и №11 должен выполняться в блоке finally и / или использовать шаблон IDisposable.
Другой основной вариант - создать RAMdrive, записать туда исполняемый файл, запустить его и очистить. Это может быть немного безопаснее, поскольку вы не пытаетесь писать самомодифицирующийся код (что в любом случае сложно, но особенно когда код даже не ваш).
Это явно запрещено в Vista +. Для этого вы можете использовать некоторые недокументированные вызовы Win32 API в XP, но в Vista + он был сломан, потому что это была огромная дыра в безопасности, и единственные люди, которые использовали его, были авторами вредоносных программ.