Вы нацеливаетесь на .NET 4.0 или более раннюю версию?
Причина, по которой я спрашиваю, заключается в том, что для CLR предусмотрена функция безопасности / стабильности, которая выполняет очень строгую проверку подписей Pinvoke; он был примерно с .NET 2.0, но по умолчанию был отключен до .NET 4.0.
Изменение поведения привело к тому, что ряд разработчиков сообщили о той же проблеме, что и вы; их привязки прекрасно работали на .NET 2.0 / 3.5, но начали генерировать ошибки при компиляции для .NET 4.0. На самом деле проблема заключается в том, что в предыдущих версиях .NET допускалось, чтобы слегка ошибочные подписи PInvoke работали без проблем; теперь, когда строгая проверка включена по умолчанию, ошибки начинают обнаруживаться.
Следует также отметить, что даже если вы измените конфигурацию на своей машине, чтобы отключить это поведение в .NET 4.0, Visual Studio все равно будет всегда использовать ее при отладке проекта. Хуже того, строгая проверка по умолчанию включена только в версии x86 .NET 4.0, а не в версии x64, поэтому сборка, которая прекрасно работает на 64-разрядной машине, может произойти сбой на 32-разрядной машине .
MSDN содержит дополнительную информацию о pInvokeStackImbalance MDA и в этом блоге , а также более подробно объясняет, почему проблема возникает в процессе отладки.
РЕДАКТИРОВАТЬ: Я только что заметил, что вы отредактировали свой вопрос, чтобы включить пример кода. Этот вид подтверждает мое подозрение о том, что подпись PInvoke была слегка неправильной. Что произойдет, если вы измените подпись с extern void *moduleCreateWithNameNative(string ModuleID)
на extern LLVMModuleRef* moduleCreateWithNameNative(string ModuleID)
?
Похоже, что здесь работает ошибка компилятора - F # не должен позволять вам определять метод с именем *moduleCreateWithNameNative
. Я предполагаю, что это разрешает (по любой причине), поэтому тип возвращаемой вашей функции компилируется как void
- и когда нативный метод пытается вернуть значение (указатель на структуру LLVMModuleRef), CLR получает споткнулся и вылетел.