我正在开发一个项目,用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#中有三个功能齐全的类,条件是每个类都将单独包装?
答案 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 internal
从public
到%module MyPointWrapper
SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
%{
#include "MyPoint.h"
%}
%include "MyPoint.h"
的一些内部功能的可见性。您只需要在导入的模块中执行此操作,因此在此实例中MyPoint.i将变为:
string
请注意,文档提供了一些更好的解决方法,而不仅仅是公开它。如果是我的生产代码,请查看这些代码。