В моем коде C # мне нужно вызвать функцию C + + (myWrapper) который экспортируется созданной мной DLL.
когда myWrapper возвращает я получаю следующую ошибку во время выполнения:
Ошибка проверки времени выполнения # 0 — значение ESP не было должным образом сохранено при вызове функции. Обычно это является результатом вызова функции, объявленной с одним соглашением о вызовах с указателем функции, объявленным с другим соглашением о вызовах.
Как я покажу ниже, я уже определил соглашения о вызовах __cdecl.
Подробно мой код C #:
class myClass
{
[DllImport("MyWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void myWrapper();
public void myMethod()
{
myWrapper();
}
}
C ++ код для myWrapper:
#include "IpIpoptApplication.hpp"
extern "C" __declspec(dllexport) void (__cdecl myWrapper)()
{
SmartPtr<IpoptApplication> solver = IpoptApplicationFactory();
ApplicationReturnStatus status = solver->Initialize();
}
IpoptAppliationFactory функция импортируется из внешней библиотеки в IpOptApplication.hpp (который является частью проекта с открытым исходным кодом и может быть просмотрен с https://projects.coin-or.org/svn/Ipopt/stable/3.11/Ipopt/src/Interfaces/IpIpoptApplication.hpp) с этой строки:
extern "C" __declspec(dllexport) class Ipopt::IpoptApplication * __cdecl IpoptApplicationFactory();
Странно то, что ошибка происходит только тогда, когда «Solver-> Initialize ()» в myWrapper называется. Если я прокомментирую вызов этого метода myWrapper возвращается без ошибок.
Проблема не связана ни с определением «Ipopt :: IpoptApplication», ни с реализацией IpoptApplicationFactory () или Initialize (), поскольку 1) они из хорошо известного проекта с открытым исходным кодом (http://www.coin-or.org/projects/Ipopt.xml) используется тысячами программистов, 2) myWrapper работает правильно, если используется в автономном исполняемом файле, написанном на коде c ++.
Я уже часами гуглил и считаю, что проблема в том, как я звоню myWrapper но я не могу найти решение.
Кто-нибудь может дать мне какое-нибудь предложение? Большое спасибо.
Роберто
Благодаря Гансу Пассанту проблема была решена. Я должен скомпилировать «myWrapper» в режиме релиза.
Библиотеки IPOPT могут быть скомпилированы только в режиме выпуска (см. Readme.txt, распространяемый с dll IpOpt)! Я установил диспетчер конфигурации для компиляции этого проекта всегда в режиме выпуска (даже когда решение находится в отладке).
Для отладки моей функции myWrapper (которая вызывает dll IpOpt) необходимо установить в свойствах моего проекта StartUp флажок «Включить отладку неуправляемого кода». Поскольку отладка неуправляемого кода не допускает изменения кода во время отладки, я продолжаю отключаться, если Мне не нужно отлаживать myWrapper.
Я надеюсь, это поможет