在 C# 中使用非托管 C++ 代码对所有双精度类型返回 0

Posted

技术标签:

【中文标题】在 C# 中使用非托管 C++ 代码对所有双精度类型返回 0【英文标题】:Using unmanaged C++ code in C# returns 0 for all type double 【发布时间】:2016-09-14 16:09:44 【问题描述】:

我正在尝试用 C++ 编写一个简单的计算器 DLL,并在我的 C# GUI 中使用该 DLL。但是,对于 double 类型的任何使用,我总是将“0”作为我的返回值。 这是 C++ 方面:

MathDLL.h

#ifndef MATH_DLL_H
#define MATH_DLL_H

#define MATHMANAGERDLL_API __declspec(dllexport)

extern "C" MATHMANAGERDLL_API double __stdcall Add(double x, double y);

#endif //MATH_DLL_H

MathDLL.cpp

#include "MathDLL.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
#define NULL 0
MathManager* mathManager;

MATHMANAGERDLL_API double __stdcall Add(double x, double y)

    if (mathManager == NULL)
        return false;

    return mathManager->add(x, y);

#ifdef _MANAGED
#pragma managed(pop)
#endif

MathManager.h

#ifndef MATH_MANAGER_H
#define MATH_MANAGER_H
class MathManager

public:
    MathManager();
    ~MathManager();

    double __stdcall add(double x, double y);
;

#endif //MATH_MANAGER_H

MathManager.cpp

#include "MathManager.h"

MathManager::MathManager()




MathManager::~MathManager()




double __stdcall MathManager::add(double x, double y)

    return x+y;

我正在像这样在 C# 中导入 DLL 函数:

SomeWinFormApp.cs

...
// Import Math Calculation Functions (MathDLL.h)
    [DllImport("MATH_DLL.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "Add")]
    public static extern double Add(double x, double y);

当我调用 Add() 时,我得到的返回值为 0。我什至将 C++ 端编辑为只是

double __stdcall MathManager::add(double x, double y)

    return 1.0;

但我仍然得到 0。这里有什么问题?我之前遇到了 PInvoke 错误,这就是我更改为 __stdcall 的原因。如果我使用 __cdecl,我仍然会得到 0。

感谢任何帮助。谢谢!

【问题讨论】:

你确定0不是这个被激活的结果吗? if (mathManager == NULL) return false;。尝试返回 50.0 而不是 false 在 C# 中如何称呼它? @Matt:我的意思是 add(double x, double y) 永远不会被调用。 C# 的 C++ 入口点是 Add 而不是 add 如果你使用return NAN而不是return false,这很多更明显,false不是一个很好的double值.创建该 MathManager 对象需要完美的概念。重点学习如何调试这段代码,Project > Properties > Debug 选项卡启用非托管调试。 @Jean-FrançoisFabre 确实!这就是问题所在。所以指针会导致问题!非常感谢! 【参考方案1】:

你声明

MathManager* mathManager;

未定义。您很幸运,它实际上是 NULL,因此您的保护代码有效并返回 false

if (mathManager == NULL) return false;

你可以在没有任何指针的情况下做很多事情:

MathManager mathManager;

MATHMANAGERDLL_API double __stdcall Add(double x, double y)
        
    return mathManager.add(x, y);

【讨论】:

以上是关于在 C# 中使用非托管 C++ 代码对所有双精度类型返回 0的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的非托管 C++ 类

在 C++ 非托管应用程序中使用 C# 托管应用程序类

从非托管 C++ mfc active x dll 启动 C# 对话框

让非托管 c++ 代码调用调用 c# 代码的托管 c++ 代码

C# 调用需要双精度数组和结构作为输入的 C++ DLL 函数

非托管 C# 与 C++ [关闭]