包装多个C++。具有多个C#.DLL的DLL 我正在研究一个用C语言包多个DLL C++ SDK的项目,试图用独立的C语言来包装每个原始的C++ DLL。我遇到了一个问题,如果C++中的一些常用符号在C++库B和C中使用,则不可能进行包装。由于这是C++中非常常见的场景,我显然忽略了一些琐碎的事情。花了几天时间,我仍然不知所措,如果有人能帮助我继续前进,我将不胜感激

包装多个C++。具有多个C#.DLL的DLL 我正在研究一个用C语言包多个DLL C++ SDK的项目,试图用独立的C语言来包装每个原始的C++ DLL。我遇到了一个问题,如果C++中的一些常用符号在C++库B和C中使用,则不可能进行包装。由于这是C++中非常常见的场景,我显然忽略了一些琐碎的事情。花了几天时间,我仍然不知所措,如果有人能帮助我继续前进,我将不胜感激,c#,c++,swig,C#,C++,Swig,以下简单示例再现了该问题: -类点应该在库A中定义 -类三角形应该在库B中定义,库B使用 -类Quadrange应该在使用 "MyPoint.h" class MyPoint { public: MyPoint(double theX, double theY) : myX(theX), myY(theY) {} double X() const { return myX; } double& X() { return myX; } double

以下简单示例再现了该问题: -类点应该在库A中定义 -类三角形应该在库B中定义,库B使用 -类Quadrange应该在使用

"MyPoint.h"
class  MyPoint
{
public:

    MyPoint(double theX, double theY) : myX(theX), myY(theY) {}

    double X() const { return myX; }
    double& X() { return myX; }

    double Y() const { return myY; }
    double& Y() { return myY; }

private:

    double myX;
    double myY;
};

"MyTriangle.h"
#include "MyPoint.h"

class MyTriangle
{
public:

    MyTriangle(const MyPoint& theP1, const MyPoint& theP2, const MyPoint& theP3) :
        myP1(theP1),
        myP2(theP2),
        myP3(theP3) {}

    MyPoint P1() const { return myP1; }
    MyPoint& P1() { return myP1; }

    MyPoint P2() const { return myP2; }
    MyPoint& P2() { return myP2; }

    MyPoint P3() const { return myP3; }
    MyPoint& P3() { return myP3; }

private:

    MyPoint myP1;
    MyPoint myP2;
    MyPoint myP3;
};

"MyQuadrangle.h"
#include "MyPoint.h"

class MyQuadrangle
{
public:

    MyQuadrangle(const MyPoint& theP1, const MyPoint& theP2, const MyPoint& theP3, const MyPoint& theP4) :
        myP1(theP1),
        myP2(theP2),
        myP3(theP3),
        myP4(theP4) {}

    MyPoint P1() const { return myP1; }
    MyPoint& P1() { return myP1; }

    MyPoint P2() const { return myP2; }
    MyPoint& P2() { return myP2; }

    MyPoint P3() const { return myP3; }
    MyPoint& P3() { return myP3; }

    MyPoint P4() const { return myP4; }
    MyPoint& P4() { return myP4; }

private:

    MyPoint myP1;
    MyPoint myP2;
    MyPoint myP3;
    MyPoint myP4;

};
三角形和四边形分别设置为三点和四点。 因此,这两个类(MyTriangle和MyQuadrangle)都使用MyPoint类。 所有三个类都单独包装。对于每个类,都有其接口文件:

"MyPoint.i"
%module MyPointWrapper
%{
#include "MyPoint.h"
%}
%include <windows.i>
%include "MyPoint.h"

"MyTriangle.i"
%module MyTriangleWrapper
%{
#include "MyTriangle.h"
%}
%include "MyPoint.i"
%include "MyTriangle.h"

"MyQuadrangle.i"
%module MyQuadrangleWrapper
%{
#include "MyQuadrangle.h"
%}
%include "MyPoint.i"
%include "MyQuadrangle.h"
出现一个错误,表示每个类都包含一种MyPoint类型: “MyPoint”类型存在于“MyTriangalNet,版本=1.0.0.0,区域性=neutral,PublicKeyToken=null”中 和“MyPointNet,版本=1.0.0.0,区域性=中立,PublicKeyToken=null”


如何避免这种情况,但在C#中有三个完全功能的类,条件是每个类都将被单独包装?

您几乎已经做到了,但是要简单地引用现有代码而不生成更多代码,您需要使用
%import“modulename.i”
而不是
%include
,因此,您的.i文件变成:

MyPoint.i:

%module MyPointWrapper
%{
#include "MyPoint.h"
%}
%include "MyPoint.h"
我的四合院

%module MyQuadrangleWrapper
%{
#include "MyQuadrangle.h"
%}
%import "MyPoint.i"
%include "MyQuadrangle.h"
MyTriangle.i:

%module MyTriangleWrapper
%{
#include "MyTriangle.h"
%}
%import "MyPoint.i"
%include "MyTriangle.h"
无论如何,我都不是C#专家,所以我希望您必须使用
%typemap(csimports)
或其他工具来确保例如MyTriangle.cs知道如何使用非限定名称引用MyPoint类型,但至少当我在Linux上用Mono测试它时,构建了一个似乎不需要的可执行文件:

#/bin/bash
swig3.0-csharp-c++-namespace geometry-outdir MyPointNet MyPoint.i
swig3.0-csharp-c++-namespace geometry-outdir mytriangelenet MyTriangle.i
swig3.0-csharp-c++-namespace geometry-outdir MyQuadrangleNet MyQuadrangle.i
g++-Wall-Wextra-o libMyPointWrapper.so MyPoint_wrapp.cxx-shared-fPIC
g++-Wall-Wextra-o libMyQuadrangleWrapper.so MyQuadrangle_wrapp.cxx-shared-fPIC
g++-Wall-Wextra-o libMyTriangleWrapper.so MyTriangle_wrap.cxx-shared-fPIC
mcs run.cs*/*.cs&&./run.exe
一旦我更改了您的示例用法,为已经存在的MyPoint调用构造函数(2-arg),所有这些都正常工作。我还在中为MyTriangle添加了一个快速测试:

MyTriangle T = new MyTriangle(P,P,P);
此外,要跨多个程序集执行此操作,您需要查看一些内部构件,从
internal
public
。您只需要在导入的模块内执行此操作,因此在本例中,MyPoint.i变为:

%module MyPointWrapper
SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
%{
#include "MyPoint.h"
%}
%include "MyPoint.h"

请注意,文档建议了一些更好的解决方法,而不仅仅是将其公开。如果它是我的生产代码,我会研究这些代码。

您几乎已经找到了它,但是要简单地引用现有代码而不生成更多代码,您需要使用
%import“modulename.I”
而不是
%include
,因此您的.I文件变成:

MyPoint.i:

%module MyPointWrapper
%{
#include "MyPoint.h"
%}
%include "MyPoint.h"
我的四合院

%module MyQuadrangleWrapper
%{
#include "MyQuadrangle.h"
%}
%import "MyPoint.i"
%include "MyQuadrangle.h"
MyTriangle.i:

%module MyTriangleWrapper
%{
#include "MyTriangle.h"
%}
%import "MyPoint.i"
%include "MyTriangle.h"
无论如何,我都不是C#专家,所以我希望您必须使用
%typemap(csimports)
或其他工具来确保例如MyTriangle.cs知道如何使用非限定名称引用MyPoint类型,但至少当我在Linux上用Mono测试它时,构建了一个似乎不需要的可执行文件:

#/bin/bash
swig3.0-csharp-c++-namespace geometry-outdir MyPointNet MyPoint.i
swig3.0-csharp-c++-namespace geometry-outdir mytriangelenet MyTriangle.i
swig3.0-csharp-c++-namespace geometry-outdir MyQuadrangleNet MyQuadrangle.i
g++-Wall-Wextra-o libMyPointWrapper.so MyPoint_wrapp.cxx-shared-fPIC
g++-Wall-Wextra-o libMyQuadrangleWrapper.so MyQuadrangle_wrapp.cxx-shared-fPIC
g++-Wall-Wextra-o libMyTriangleWrapper.so MyTriangle_wrap.cxx-shared-fPIC
mcs run.cs*/*.cs&&./run.exe
一旦我更改了您的示例用法,为已经存在的MyPoint调用构造函数(2-arg),所有这些都正常工作。我还在中为MyTriangle添加了一个快速测试:

MyTriangle T = new MyTriangle(P,P,P);
此外,要跨多个程序集执行此操作,您需要查看一些内部构件,从
internal
public
。您只需要在导入的模块内执行此操作,因此在本例中,MyPoint.i变为:

%module MyPointWrapper
SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
%{
#include "MyPoint.h"
%}
%include "MyPoint.h"

请注意,文档建议了一些更好的解决方法,而不仅仅是将其公开。如果是我的生产代码,我会仔细研究这些代码。

非常感谢您提供的提示。在我将%模块添加到Triangle.I文件中之后,我遇到了从为Triangle生成的代码中访问MyPoint类的方法的问题(与Qudrangle相同)。原始帖子编辑了更多细节。@KKrill如果您使用
-Wall
运行SWIG,它会发出很多关于
internal
是C#中的保留字的警告。我的猜测是,这与此有关。实际上可能不是,似乎这是一些我以前没有经验的C#modules东西。我再挖一点,明白了。接下来是一个编辑。事实证明,这正是我在展示使用Mono编译之前提到的问题,但文档中已经有了更简洁的解决方案。非常感谢您的详细回答。它帮助我解决了我的问题!非常感谢你给我一个提示。在我将%模块添加到Triangle.I文件中之后,我遇到了从为Triangle生成的代码中访问MyPoint类的方法的问题(与Qudrangle相同)。原始帖子编辑了更多细节。@KKrill如果您使用
-Wall
运行SWIG,它会发出很多警告