【问题标题】:Build DLL (MyMathFuncs) for use in Python Ctypes构建用于 Python Ctypes 的 DLL (MyMathFuncs)
【发布时间】:2013-08-08 18:20:51
【问题描述】:

作为一个 C++ 新手,我刚刚按照here 找到的 MS 教程创建了我的第一个动态链接库

头文件内容如下:

// MathFuncsDll.h

namespace MathFuncs
{
    class MyMathFuncs
    {
    public:
        // Returns a + b
        static __declspec(dllexport) double Add(double a, double b);

        // Returns a - b
        static __declspec(dllexport) double Subtract(double a, double b);

        // Returns a * b
        static __declspec(dllexport) double Multiply(double a, double b);

        // Returns a / b
        // Throws DivideByZeroException if b is 0
        static __declspec(dllexport) double Divide(double a, double b);
    };
}

现在,我想将这个文件读入 Python ctypes。我这样做是:

import ctypes as ctypes

MyDll = 'MathFuncsDll.dll'
MyFuncs = ctypes.cdll.LoadLibrary(MyDll)

现在,我正在努力实际访问这些功能。我的直觉引导我尝试

a = ctypes.c_double(54)
b = ctypes.c_double(12)

summation = MyFuncs.Add(a,b)

返回错误

AttributeError: function 'Add' not found

我的问题是该函数嵌套在class MyMathFuncs 中,而namespace MathFuncs 也在namespace MathFuncs 中吗?如何访问这些功能?

供参考,下面是用于生成dll的.cpp文件的内容

// MathFuncsDll.cpp
// compile with: /EHsc /LD

#include "MathFuncsDll.h"

#include <stdexcept>

using namespace std;

namespace MathFuncs
{
    double MyMathFuncs::Add(double a, double b)
    {
        return a + b;
    }

    double MyMathFuncs::Subtract(double a, double b)
    {
        return a - b;
    }

    double MyMathFuncs::Multiply(double a, double b)
    {
        return a * b;
    }

    double MyMathFuncs::Divide(double a, double b)
    {
        if (b == 0)
        {
            throw new invalid_argument("b cannot be zero!");
        }

        return a / b;
    }
}

【问题讨论】:

    标签: python dll ctypes


    【解决方案1】:

    您无法使用 ctypes 访问 C++ 类和命名空间。 C++ 没有标准的二进制接口,就像 C 一样。每个编译器都为相同的 C++ 动态库输出它自己的(不同的)二进制文件。你可以阅读更多关于它的信息here

    可以做的事情(如果你必须用 C++ 做的话)就是用 C++ 做你所有的工作,然后编写一个很小的 ​​C 层来包装和公开它。然后您就可以使用ctypes 访问它。同样,您可以阅读它here

    【讨论】:

    • 这很有帮助。谢谢。您知道是否有一种直接的方法来制作“C”DLL 而不是“C++”DLL?这个 DLL 本质上是什么 C++(当然,除了使用 C++ 编译器)。
    • 不确定您的问题到底是什么?您可以创建一个 C DLL,使用 C 编译器编译 C 代码或使用 extern "C" { 公开 C++ 代码。 DLL 有其二进制接口,但不幸的是,由于名称处理和/或库函数调用之间管理堆栈的不同方式,不同的 C++ 编译器会为相同的 C++ 代码输出不同的二进制文件。
    • 嗯...那么您究竟会在 extern C 括号中包含什么?是否需要对 cpp 和头文件进行类似的调整?
    • 这有点离题了。在stackoverflowmany other places 的很多地方都有解释...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 2012-11-01
    • 1970-01-01
    相关资源
    最近更新 更多