[英]Wrapping multiple C++ .dlls with multiple C# .dlls
我正在開發一個項目,用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“C:\\ Geometrics \\ MyPointcpp”-outdir C:\\ Geometrics \\ MyTriangleNet \\ Generated MyTriangle.i C:\\ swigwin-3.0.10 \\ swigwin-3.0.10 \\ swig -csharp -c ++ -namespace geometry -I“C:\\ Geometrics \\ MyPointcpp”-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類型:'MyTriangleNet,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'和'MyPointNet,Version = 1.0.0.0,Culture =中性,PublicKeyToken = null'
如何避免這種情況,但在C#中有三個功能齊全的類,條件是每個類將被單獨包裝?
您幾乎已經實現了它,但是為了簡單地引用現有代碼而不產生更多,您需要使用%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);
此外,為了使這項功能適用於多個程序集,您需要執行更多工作(如文檔中所述),以更改某些內部組件從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"
請注意,文檔提供了一些更好的解決方法,而不僅僅是公開它。 如果是我的生產代碼,我會調查那些。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.