-1

In my c# code I need to call a c++ function (myWrapper) that is exported by a dll that I've created.

When myWrapper returns I get the following runtime error:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

As I will show below, I already specified the calling conventions a __cdecl.

In detail, my C# code:

class myClass
{
    [DllImport("MyWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern void myWrapper();

    public void myMethod()
    {
        myWrapper();
    }
}

c++ code for myWrapper:

#include "IpIpoptApplication.hpp"

extern "C" __declspec(dllexport) void (__cdecl myWrapper)()
{
    SmartPtr<IpoptApplication> solver = IpoptApplicationFactory();
    ApplicationReturnStatus status = solver->Initialize();  
}

The IpoptAppliationFactory function is imported from an external dll in IpOptApplication.hpp (which is part of an open source project and can be viewed from https://projects.coin-or.org/svn/Ipopt/stable/3.11/Ipopt/src/Interfaces/IpIpoptApplication.hpp) with this line:

extern "C" __declspec(dllexport) class Ipopt::IpoptApplication * __cdecl IpoptApplicationFactory();

The strange thing is that the error happens only when "solver->Initialize()" in myWrapper is called. If I comment the call to this method myWrapper returns without errors. The problem is not related to the definition of "Ipopt::IpoptApplication", nor in the implementation of IpoptApplicationFactory() or Initialize() because 1) they are from a well known open source project (http://www.coin-or.org/projects/Ipopt.xml) used by thousands of programmers, 2) myWrapper works correctly if used in a standalone executable written in c++ code.

I've already googled for hours and I believe that the problem is in the way I call myWrapper but I can't find a solution.

Can anyone give me some suggestion? Thanks a lot.

Roberto

Homer1982
  • 441
  • 4
  • 16
  • 1
    Could be a problem in the code that we cannot see – David Heffernan Jan 08 '15 at 11:47
  • I'd check the answer on this question: http://stackoverflow.com/questions/18614054/the-value-of-esp-was-not-properly-saved-across-a-function-call-error – Jcl Jan 08 '15 at 11:52
  • You are linking to version 3.11 of the library. But if you look at, say version 3.9.3 then you see that the initialize() method takes an argument. Kaboom if you call it without one. Standard DLL Hell. – Hans Passant Jan 08 '15 at 13:16
  • @HansPassant: I'm using the latest version of IpOpt, that actually is 3.11 ([link](http://www.coin-or.org/projects/Ipopt.xml)). Please note that the error happens not on the initialize() call but when myWrapper returns (if initialize() have been called before). – Homer1982 Jan 08 '15 at 13:17
  • This diagnostic is generated by C++ code, not by C# code. You are simply not using the version you think you are, look at the DLL properties in Explorer. – Hans Passant Jan 08 '15 at 13:21
  • @HansPassant: I've double checked and I'm using dll version 3.11 of [IpOpt-vc10.dll](http://www.coin-or.org/download/binary/Ipopt/Ipopt-3.11.0-Win32-Win64-dll.7z) along with this [IpIpoptApplication.hpp](https://projects.coin-or.org/svn/Ipopt/stable/3.11/Ipopt/src/Interfaces/IpIpoptApplication.hpp) – Homer1982 Jan 08 '15 at 13:42
  • @DavidHeffernan: Please, let me know which part of the code should I add. I can also give you a link with the Visual Studion 2010 sample solution. – Homer1982 Jan 08 '15 at 13:45
  • @DavidHeffernan: I checked your suggested answer but in that question there isn't any dll import. So even if the error is the same I think that the solution is completely different. Anyway I applied that solutin but without luck. – Homer1982 Jan 08 '15 at 13:52
  • @Homer1982 I didn't suggest an answer – David Heffernan Jan 08 '15 at 13:54
  • The warning in the README.TXT file is very important. – Hans Passant Jan 08 '15 at 14:02

1 Answers1

0

Thanks to Hans Passant the problem has been solved. I must compile "myWrapper" in release mode.

IPOPT DLLS CAN BE COMPILED ONLY IN RELEASE MODE (see readme.txt distributed with IpOpt dlls)! I've set the configuration manager to compile this project always in release mode (even when the solution is in debug). To debug my myWrapper function (which calls IpOpt dlls), it's necessary to set in the properties of my StartUp project, the check box "Enable unmanaged code debugging" Since unmanaged code debugging does not allow code modifications during debug, I keep diabled this if I don't need to debug myWrapper.

I hope this will help

Homer1982
  • 441
  • 4
  • 16