Решил поделиться граблями, на которые давеча с размаху наступил (грабли не мои, моя только шишка
).
Итак, дано:
.NET-библиотека (dll), скомпилированная для x86 (WIN32) - в моём случае это была библиотека на Managed C++;
.NET-приложение, написанное на C#, с дефолтной опцией платформы.
Результат: на x86-машине исполняется без проблем. На x64 при попытке исполнения генерируется исключение: библиотека не может быть подгружена.
По сути, происходит следующее: поскольку целевая платформа для приложения не была указана явно, то на 64-битной машине фреймворк без зазрения совести использует 64-битную версию. А 32-битную зависимость подгружает уже в рантайме, и тут оказывается, что она "плохая" - фреймворк ожидает, что библиотека тоже будет для 64-битной платформы.
Таким образом, можно на 32-битной (да и на x64 тоже) машине собрать приложение, которое будет работать вполне нормально до тех пор, пока не повстречается с 64-битной. Причём, всё это без каких-либо ошибок компиляции или предупреждений со стороны среды (компилировал в VS 2008). То есть, тот факт, что некоторые зависимости являются 32-битными, спокойно игнорируется средой на дефолтных настройках (Properties->Build->Platform target: "Any CPU").
Более того, среда вводит в заблуждение: когда я добавляю зависимости типа System.Drawing руками в references проекта, пути к этим библиотекам отображаются для 32-битного фреймворка (C:\Windows\Microsoft.NET\Framework).
Лекарство очевидно: если есть 32-битные динамические зависимости (references), то приложение тоже компилировать в 32 бита. Тогда на x64 всё будет спокойно работать с 32-битной версией .NET.
Однако если не помнить об этом заранее, можно потратить кучу времени, пытаясь понять, почему же оно валится на твоей конкретной машине, тогда как у автора проекта "всё работает", и у тебя код собирается.