Я пишу программу на .NET 3.5, которая в некоторых местах должна выходить и выполнять код из аппаратных API. Это все хорошо и работает в 32-битной Windows 7, Windows XP и т. Д. Проблема связана с 64-битной Windows 7.
Я компилирую в «Любой процессор», и он работает в 64-битной версии в Windows 7 64-битной. Таким образом, для взаимодействия с этим единым оборудованием мне пришлось написать свою собственную DLL-оболочку на неуправляемом C ++.
Итак, после того, как у меня все это заработало в 32 битах, я переключил переключатели, чтобы перейти на 64 бит, и в этом заключается проблема. Проблема, с которой я столкнулся, в значительной степени является ТОЧНОЙ противоположностью вопроса переполнения стека «Была предпринята попытка загрузить программу с неверным форматом», даже если платформы одинаковы . В этом вопросе он пытается заставить свой код работать в 32-битном режиме (принудительно) в Windows 7.
Хорошо, теперь я не хочу этого делать, поскольку существует IS 64-битный API для этого аппаратного обеспечения. Итак, я скомпилировал мой код в 64-битной среде, а затем, после многих проб и ошибок, получил правильное LINK в 64-битной версии, и у меня есть PURE 64-битная C ++ DLL и Depends.exe
подтверждает это. Теперь Depends.exe
также отображает файл DLL поставщика как чистый 64-битный. Это хорошо, потому что в первый раз код не работал, я начал исследование с производителем, и они немного обновили свой код с моей помощью, или я должен сказать, с моими ПРОБЛЕМАМИ ...:)
Итак, короткая история, я разбил это на настолько простую установку, насколько смог. Мой DLL-файл, HW API.dll
(который также является родным C ++) и приложение .NET для их вызова с использованием того же синтаксиса P / Invoke и вызовов в качестве 64-битной версии. ..
Мои звонки, просто для справки, выглядят так:
[DllImport("xBiometrics.dll", ExactSpelling=true, SetLastError=true)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern Int32 bioScanOpenDevice();
Теперь, когда я пытаюсь вызвать этот код из .NET, я получаю ошибку исключения:
"System.BadImageFormatException:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)"
Это заставляет меня поверить, что НЕКОТОРЫЕ, что-то 32-битное вмешивается ... Как я мог это сказать? Я имею в виду, да, я уже заглянул в обозреватель ресурсов и убедился, что файлы DLL загружаются из правильного места, и опять же, они скомпилированы в 64-разрядной версии, а приложение .NET работает в 64-разрядной версии. , хотя он скомпилирован для «Любой процессор». Я все это проверил ...
Я что-то совершенно тупой? Я пропустил абзац, где говорится, что P / Invoke не работает на 64-разрядных или что-то? И если я это сделал, то почему он выбрасывает плохой формат изображения исключение?
Возможно ли то, что я делаю, или нет? Может ли 64-битное приложение .NET загружать и вызывать 64-битный собственный DLL-файл? И может ли этот файл DLL динамически связываться с другим собственным 64-разрядным файлом DLL? Будет ли иметь значение, если я использую управляемый 64-битный файл DLL в качестве файла DLL клина? Я использую только DLL-файл клина из-за некоторых вызовов в DLL-файле производителя оборудования. Они передают пустые указатели в буферы, и тому подобное, и это должно быть слишком сложно сделать в C # (необходимо проверить «Разрешить небезопасный код» и т. Д.) Итак, моя идея клина сработала намного лучше ... Я делаю все тяжелая работа в C ++ и передача более структурированных данных в код C #.