swift执行系统命令 swift dll_c++


使用C++开发界面,时间效率上来说,不如C#开发的快和方便。但是CTP的库是C++的,并没有C#的库,网上也有人用C#的PINVOKE的方式将C++的函数一个个转换为C#能用的接口,我是看了下,原理ok,但是真心转换起来工作量太大了。

借鉴

swig把CTP转javablog.csdn.net


这篇文章,我想swig转C#这个方式应该更容易,于是今天先写一个demo,然后尝试着转转看。先参考如下的一个基础例子。

swig转C#blog.csdn.net


swig是将C++原始代码,包装成一个方便其他语言调用的工具。

swig转C#主要做两步操作:

  1. 将C++代码进行一次封装,生成wrap未文件名结尾的C++文件,这些warp文件中会创建一些新的方法,这些新方法是对于开发人员而言是透明的,它们不是给开发人看的,而是给其他语言使用的。生成的dll中包含这些新方法。
  2. 同时生成C#对应的类文件,这些类文件需要拷贝到C#项目中,这些类对应于原始C++中的类名和方法名,这样就可以做到在C#中访问和原始C++项目中一样的类和方法。 实际上这一步做的工作就是调用上一步产生的wrap中的方法,wrap中的方法再去调用原始C++的方法。

但是现在还有一个问题:

以上C#的例子中,没有继承实现和回调这两种实现。只有解决了这两个问题,才能进一步转换CTP的类库。

首先得解决这个,于是自己在其基础上,按照如下7步骤生成一个可以被C#方便使用的C++的dll。

一、利用Swig生成C#方便使用的DLL

step 1 : 创建了如下项目,一个C++动态链接库的项目,一个C#桌面应用程序。


swift执行系统命令 swift dll_#include_02


step 2 :其中c++_file.idl文件内容如下,这个文件是swig转换规则的定义文件,同时,要修改该文件属性,否则项目编译会把该文件也编译进去,会报错的。右键该文件属性:项类型->自定义生成工具


%module(directors = "1") cppdll   /*directors = "1",才可以使用虚函数的多态特性,否则只能继承,不能多态*/
%{
/* 在包装代码中包含头文件 */
#include "c++_file.h"  
%}
%feature("director") Addmethod;  /*需要指明多态的类,若module(directors = "1")未声明,则此处没有意义*/

/* 解析头文件生成包装代码 */
%include "c++_file.h"


step 3 :c++_file.h


#pragma once
class Addmethod
{
public:
	virtual int add(int a, int b) { return 0; };
	virtual ~Addmethod() {}
};

class CPlusPlusClass
{
public:
	//加法计算实际上是通过Addmethod.add实现
	int Add(int a,int b,Addmethod* method);
};


step 4 :C++_project.cpp


// C++_project.cpp: 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "c++_file.h"  
int CPlusPlusClass::Add(int a, int b,Addmethod* method)
{
	if(method)
		return method->add(a,b);
	else 
		return a + b;
}


step 5 :以上代码写好后,就可以使用swig进行转换了,命令行切换到项目c++_file.idl所在目录,输入如下命令,(swig已经加到系统的环境变量中才可以直接使用命令,否则需要全路径)


swig -c++ -csharp c++_file.idl


step 6 :运行没有报错,则会生成如下文件,将其中后缀为.cs的文件全部拷贝到C#项目中。


swift执行系统命令 swift dll_swift执行系统命令_03


step 7 :在C++_project项目上,会看到debug目录下有生成一个C++_project.dll文件。将该文件拷贝到C#项目的debug目录下。


swift执行系统命令 swift dll_多态_04


二、C#使用上述DLL

在C#项目中,使用代码如下:

  • 创建子类ChildMethod 继承C++的Addmethod类,并重写方法add
  • 创建子类Child类,继承C++中的CPlusPlusClass类,并新增方法showChild
  • 调用child对象,并将childMethod对象传入,以便C++的dll库进行多态回调。
class ChildMethod : Addmethod
        {
            public override int add(int i,int j)
            {
                return (i+j)*100;
            }
        }
        class Child:CPlusPlusClass
        {
            public string showChild()
            {
                return ("child");
            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
            Addmethod method = new ChildMethod();
            Child child = new Child();
            
            richTextBox1.Text += DateTime.Now.ToLongTimeString() + " " + child.Add(3, 3, method)+ "n";
        }


总结

整体而言,利用swig封装C++为C#的调用方式,可以极大的减轻工作量,同时方便后续高效率的开发使用原先的C++库。