-1

在我的 c# 代码中,我需要调用由我创建的 dll 导出的 c++ 函数 ( myWrapper )。

myWrapper返回时,我收到以下运行时错误:

运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是调用使用一种调用约定声明的函数和使用另一种调用约定声明的函数指针的结果。

正如我将在下面展示的,我已经将调用约定指定为 __cdecl。

详细来说,我的 C# 代码:

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

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

myWrapper的 c++ 代码:

#include "IpIpoptApplication.hpp"

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

IpoptAppliationFactory函数是从IpOptApplication.hpp中的外部 dll 导入的(这是一个开源项目的一部分,可以从https://projects.coin-or.org/svn/Ipopt/stable/3.11/Ipopt/src查看/Interfaces/IpIpoptApplication.hpp)与这一行:

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

奇怪的是,只有在调用 myWrapper 中的“ solver- >Initialize()”时才会发生错误。如果我评论对此方法的调用myWrapper将返回而没有错误。该问题与“Ipopt::IpoptApplication”的定义无关,也与 IpoptApplicationFactory() 或 Initialize() 的实现无关,因为 1)它们来自一个众所周知的开源项目(http://www.coin-or .org/projects/Ipopt.xml)被成千上万的程序员使用,2)如果在用 c++ 代码编写的独立可执行文件中使用 myWrapper,则可以正常工作。

我已经用谷歌搜索了几个小时,我相信问题出在我调用myWrapper的方式上,但我找不到解决方案。

谁能给我一些建议?非常感谢。

罗伯托

4

1 回答 1

0

多亏了 Hans Passant,问题才得以解决。我必须在发布模式下编译“myWrapper”。

IPOPT DLL 只能在发布模式下编译(请参阅随 IpOpt dll 分发的 readme.txt)!我已将配置管理器设置为始终以发布模式编译此项目(即使解决方案处于调试状态)。要调试我的 myWrapper 函数(调用 IpOpt dll),有必要在我的 StartUp 项目的属性中设置复选框“启用非托管代码调试”由于非托管代码调试不允许在调试期间修改代码,如果我不需要调试 myWrapper。

我希望这个能帮上忙

于 2015-01-14T07:28:46.663 回答