用多个C#.dll包装多个C ++ .dll

时间:2017-01-19 14:41:31

标签: c# c++ swig

我正在开发一个项目,用C#包装一个多dll C ++ SDK,尝试用独立的C#dll包装每个原始的C ++ dll。我遇到了一个问题,如果在C ++库B和C中使用C ++库A中的某些常用符号,则无法进行换行。因为在C ++中这是一个非常频繁的场景,显然我想念一些微不足道的东西。花了几天我仍然感到茫然,并希望得到任何帮助,如何继续前进。

以下简单示例再现了该问题: - 类Point应该在库A中定义 - 类Triangle应该在库B中定义,它使用A - 类Quadrange应该在库C中定义,它使用A

"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"

为每个文件编写了命令行界面: C:\ swigwin-3.0.10 \ swigwin-3.0.10 \ swig -csharp -c ++ -namespace geometry -outdir C:\ Geometrics \ MyPointNet \ Generated MyPoint.i C:\ swigwin-3.0.10 \ swigwin-3.0.10 \ swig -csharp -c ++ -namespace geometry -I&#34; C:\ Geometrics \ MyPointcpp&#34; -outdir C:\ Geometrics \ MyTriangleNet \ Generated MyTriangle.i C:\ swigwin-3.0.10 \ swigwin-3.0.10 \ swig -csharp -c ++ -namespace geometry -I&#34; C:\ Geometrics \ MyPointcpp&#34; -outdir C:\ Geometrics \ MyQuadrangleNet \ Generated MyQuadrangle.i

当我在C#中使用MyPoint类时:

using System;
using geometry;

namespace Example
{
        class Program
        {
            static void Main(string[] args)
            {
                MyPoint P = new MyPoint (3, 4, 5);
            }
        }
}

出现一个错误,表示每个类都包含一种MyPoint: 类型&#39; MyPoint&#39;存在于&#39; MyTriangleNet,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39; 和&#39; MyPointNet,版本= 1.0.0.0,文化=中立,PublicKeyToken = null&#39;

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

1 个答案:

答案 0 :(得分:0)

您几乎已经在那里了,但是为了简单地引用现有代码而不产生更多代码,您需要使用%import "modulename.i"而不是%include,因此您的.i文件变为:

MyPoint.i:

%module MyPointWrapper
%{
#include "MyPoint.h"
%}
%include "MyPoint.h"

MyQuadrangle.i:

%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 MyTriangleNet MyTriangle.i
swig3.0 -csharp -c++ -namespace geometry -outdir MyQuadrangleNet MyQuadrangle.i

g++ -Wall -Wextra -o libMyPointWrapper.so MyPoint_wrap.cxx -shared -fPIC
g++ -Wall -Wextra -o libMyQuadrangleWrapper.so MyQuadrangle_wrap.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);

此外,要使这项功能适用于多个程序集,您需要a little more work, as outlined in the documentation, to change internalpublic%module MyPointWrapper SWIG_CSBODY_PROXY(public, public, SWIGTYPE) SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE) %{ #include "MyPoint.h" %} %include "MyPoint.h" 的一些内部功能的可见性。您只需要在导入的模块中执行此操作,因此在此实例中MyPoint.i将变为:

string

请注意,文档提供了一些更好的解决方法,而不仅仅是公开它。如果是我的生产代码,请查看这些代码。