По вашему первому вопросу: я делаю обоснованное предположение и не говорю из опыта, но мне кажется, что во втором случае освобождение памяти будет называться "в .exe". Когда вы вызываете delete object;
, происходят две вещи: во-первых, вызываются деструкторы, а во-вторых, освобождается память для объекта. Первая часть, вызов деструктора, определенно будет работать, как вы ожидаете, вызывая правильные деструкторы в вашей dll. Однако, так как shared_ptr является шаблоном класса, его деструктор генерируется в вашем .exe, и поэтому он будет вызывать оператор delete () в вашем exe, а не тот, что в .dll. Если они были связаны с разными версиями времени выполнения (или даже статически связаны с одной и той же версией времени исполнения), это должно привести к ужасному неопределенному поведению (в этой части я не совсем уверен, но, похоже, логично так) , Есть простой способ проверить, является ли то, что я сказал, правдой - переопределить глобальный оператор delete в вашем exe, но не в вашей dll, поместите в него точку останова и посмотрите, что вызывается во втором случае сделай это сам, но у меня так много времени, чтобы расслабиться, к сожалению).
Обратите внимание, что та же самая ошибка существует для первого случая (вы, кажется, это понимаете, но на всякий случай). Если вы делаете это в exe:
IBase *p = CreateInterface();
delete p;
тогда вы находитесь в том же самом операторе вызова, новом в dll, и вызове оператора delete в exe. Вам понадобится либо соответствующая функция DeleteInterface (IBase * p) в вашей dll, либо метод Release () в IBase (который не должен быть виртуальным, просто не встроенным) для единственной цели вызова нужной памяти функция освобождения.