简体   繁体   English

使用SWIG从包装的cpp文件创建DLL

[英]Creating a DLL from a wrapped cpp file with SWIG

I am in the process of learning how to use SWIG on Windows. 我正在学习如何在Windows上使用SWIG。

The following is my c++ code: 以下是我的c ++代码:

 /* File : example.cxx */

 #include "example.h"
 #define M_PI 3.14159265358979323846

/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
    x += dx;
    y += dy;
 }

int Shape::nshapes = 0;

double Circle::area(void) {
   return M_PI*radius*radius;
}

double Circle::perimeter(void) {
  return 2*M_PI*radius;
}

double Square::area(void) {
  return width*width;
}

 double Square::perimeter(void) {
   return 4*width;
 }

This is my header file: 这是我的头文件:

/* File : example.h */

   class Shape {
   public:
     Shape() {
     nshapes++;
   }
  virtual ~Shape() {
   nshapes--;
 };
  double  x, y;   
  void    move(double dx, double dy);
  virtual double area(void) = 0;
  virtual double perimeter(void) = 0;
  static  int nshapes;
  };

 class Circle : public Shape {
 private:
   double radius;
 public:
   Circle(double r) : radius(r) { };
   virtual double area(void);
   virtual double perimeter(void);
 };

 class Square : public Shape {
 private:
   double width;
 public:
   Square(double w) : width(w) { };
   virtual double area(void);
   virtual double perimeter(void);
 };

This is my interface file: 这是我的界面文件:

 /* File : example.i */
 %module example

 %{
 #include "example.h"
 %}

 %include "example.h"

I have managed to wrap my c++ code with the following command in Cygwin using SWIG: 我已经设法使用SWIG在Cygwin中使用以下命令包装我的c ++代码:

  $swig -c++ -python -o example_wrap.cpp example.i 

My question is, how do I create a DLL from this point forward using the generated code (example_wrap.cpp)? 我的问题是,如何使用生成的代码(example_wrap.cpp)从这一点开始创建DLL? Any ideas? 有任何想法吗?

I tried creating a DLL with Visual Studio C++ 2010 but I get the build error: 我尝试使用Visual Studio C ++ 2010创建DLL,但是我收到了构建错误:

LINK : fatal error LNK1104: cannot open file 'python27_d.lib

I'm fairly new to using SWIG so any help would be greatly appreciated. 我是使用SWIG的新手,所以任何帮助都将非常感激。

Thanks! 谢谢!

add MS_NO_COREDLL definition at Configuration Properties->C/C++->Preprocessor->Preprocessor Definitions; 在Configuration Properties-> C / C ++ - > Preprocessor-> Preprocessor Definitions中添加MS_NO_COREDLL定义; or add #define MS_NO_COREDLL line before including python.h. 或者在包含python.h之前添加#define MS_NO_COREDLL行。

#define MS_NO_COREDLL
#include <Python.h>

If you look in the libs directory of your Python installation I suspect you will find a python27.lib and not a python27_d.lib. 如果查看Python安装的libs目录,我怀疑你会发现python27.lib而不是python27_d.lib。 I believe that the _d.lib is the debug version of the Python library and your Python installation didn't include it. 我相信_d.lib是Python库的调试版本,并且您的Python安装不包含它。 Elsewhere I've seen it suggested that the simplest way around this is to download the Python sources and build the release and debug versions yourself but I've never tried this. 在其他地方,我已经看到它建议最简单的方法是下载Python源代码并自己构建发布和调试版本,但我从未尝试过这个。 Alternatively change you build to use the release version of the Python .lib. 或者,更改构建以使用Python .lib的发行版。 You should be able to debug your own code but not the Python code then. 您应该能够调试自己的代码,但不能调试Python代码。

The problem seems to be that, for unknown reasons, the file pyconfig.h FORCES the use of a specifically named .lib file. 问题似乎是,由于未知原因,文件pyconfig.h FORCES使用了一个专门命名的.lib文件。 OUCH! 哎哟! Frankly, this looks like a bug to me - let the programmer specify what .lib file to use! 坦率地说,这看起来像是一个错误 - 让程序员指定使用什么.lib文件! Don't force it! 不要强迫它!

In the code below, you could simply #ifdef 0 the entire thing, or rename "python27_d" to "python". 在下面的代码中,您可以简单地#ifdef 0整个事物,或者将“python27_d”重命名为“python”。

Anyway, here is the offensive code from pyconfig.h: 无论如何,这是来自pyconfig.h的令人反感的代码:

/* For an MSVC DLL, we can nominate the .lib files used by extensions
*/
#ifdef MS_COREDLL
#   ifndef Py_BUILD_CORE /* not building the core - must be an ext */
#       if defined(_MSC_VER)            /* So MSVC users need not specify the .lib file in          their Makefile (other compilers are generally           taken care of by distutils.) */
#           ifdef _DEBUG
#               pragma comment(lib,"python27_d.lib")
#           else
#               pragma comment(lib,"python27.lib")
#           endif /* _DEBUG */
#       endif /* _MSC_VER */
#   endif /* Py_BUILD_CORE */
#endif /* MS_COREDLL */

SWIG (at least on v3.0) generates the python.h inclusion in the wrapper as follows: SWIG(至少在v3.0上)在包装器中生成python.h包含如下:

#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
/* Use debug wrappers with the Python release dll */
# undef _DEBUG
# include <Python.h>
# define _DEBUG
#else
# include <Python.h>
#endif

So when compiling a debug version of the wrapper on a Windows platform, we simply need to define the SWIG_PYTHON_INTERPRETER_NO_DEBUG flag to avoid the pyconfig.h file issue mentioned in Ken's answer. 因此,在Windows平台上编译包装器的调试版本时,我们只需要定义SWIG_PYTHON_INTERPRETER_NO_DEBUG标志,以避免Ken的答案中提到的pyconfig.h文件问题。

Building the project in Release mode removes the python27_d.lib dependency too; 在Release模式下构建项目也会删除python27_d.lib依赖项; at least it did for my own project. 至少它是为我自己的项目做的。

I found out that addind the Python symbols do the Project solves it. 我发现addind Python符号是Project解决它的。 Do it like this 做到像这个

I also copied the python27.lib to a file named python27_d.lib 我还将python27.lib复制到名为python27_d.lib的文件中

You can try adding "python27_d.lib" (without quotes) to ignored libs: 您可以尝试将“python27_d.lib”(不带引号)添加到忽略的库中:

Configuration Properties -> Linker -> Input -> Ignore Specific Library 配置属性 - >链接器 - >输入 - >忽略特定库

I resolved the missing python27_d.lib by doing the following: 我通过执行以下操作解决了缺少的python27_d.lib:

  • Copy python27.lib to python27_d.lib 将python27.lib复制到python27_d.lib
  • In pyconfig.h comment out define Py_DEBUG 在pyconfig.h中注释掉define Py_DEBUG

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM