Во-первых, вопрос: выполняют ли спецификации CLR, что код, выполняемый в нескольких доменах приложения в одном и том же процессе, будет иметь одно и то же адресное пространство? "Совместное использование адресного пространства" означает, что указатели на память, выделенные в одном из доменов приложений, будут действительны для чтения и записи во всех доменах приложений, размещенных внутри одного процесса.
Рассмотрим этот самодостаточный пример, иллюстрирующий вопрос: программа выделяет объект Worker
в отдельном домене приложения. Worker
выделяет блок памяти для 10 000 целых чисел и заполняет его данными. Затем программа перебирает границу домена приложения, чтобы получить указатель на выделенный блок, и проверяет, что он может читать каждый из 10 000 элементов.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace crossapp {
public class Worker : MarshalByRefObject {
private readonly IntPtr myData;
public const int DataLength = 10000;
public Worker() {
Console.Error.WriteLine(
"Memory allocation happens in app domain '{0}'"
, Assembly.GetExecutingAssembly().FullName
);
myData = Marshal.AllocHGlobal(sizeof(int) * DataLength);
unsafe {
var ptr = (int*) myData.ToPointer();
for (var i = 0 ; i != DataLength ; i++) {
ptr[i] = 2*i + 1;
}
}
}
public IntPtr GetData() {
return myData;
}
}
class Program {
static void Main() {
var ad = AppDomain.CreateDomain("New domain");
var wrk = (Worker)ad.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName
, "crossapp.Worker"
);
var data = wrk.GetData();
var badCount = 0;
unsafe {
var ptr = (int*)data.ToPointer();
for (var i = 0 ; i != Worker.DataLength ; i++) {
var expect = 2*i + 1;
if (ptr[i] != expect) {
Console.Error.WriteLine(
"Mismatch in position {0}: {1} != {2}"
, i, expect, ptr[i]
);
badCount++;
}
}
if (badCount == 0) {
Console.Error.WriteLine(
"All {0} items have matched."
, Worker.DataLength
);
} else {
Console.Error.WriteLine(
"Found {0} mismatches out of {1}."
, badCount
, Worker.DataLength
);
}
}
}
}
}
Я работал много раз, и он работал каждый раз. Интуитивно он должен работать: ведь домены приложений находятся в рамках одного процесса, поэтому они должны совместно использовать одно и то же виртуальное адресное пространство. Однако это похоже на использование функции, которую Microsoft может отнять в любой момент. Есть ли что-то в спецификации CLR, которая подтверждает или отрицает легитимность этого трюка?
В случае, если вам интересно, почему я задаю такой странный вопрос, я ищу способ передачи больших (в гигабайтах) объемов данных через границу домена приложения с минимальными накладными расходами как в пространстве, так и во времени. Это было бы идеальным решением, если бы я мог доказать свою легитимность.