C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

C#的Form通过CLI调用C++的DLL


一 方法

         C#的project调用C++的DLL,一般也有3中方法:
         1)最简单的方法,通过PInvoke,但是只能调用全局function,不能调用Class。
         2)通过COM封装调用。
         3)通过CLI作为中介,也即本文章所讲的。

二 实例

1)假如我们有的Math的dll,
class CPPDLL_API Math
{
public:
    
static double Add(double x, double y);
    
static double Multiply(double x, double y);
}
;

class CPPDLL_API AdvancedMath
{
public:
    
static int Factorial(int x);
}
;

double Math::Add(double x, double y)
{
    
return x + y;
}

double Math::Multiply(double x, double y)
{
    
return x * y;
}

int AdvancedMath::Factorial(int x)
{
    
if(x <= 0)
        
return 0;
    
if(1 == x)
        
return 1;
    
return x * Factorial(x - 1);
}

2)C++的MFC的Dialog调用(比较烦,特别是MFC的controls太少了。各种String间的转化也和累啊,我这里为了简化,不得不把vs05中默认的unicode改为非unicode)
#pragma comment(lib,"../debug/cppdll.lib")
#include 
"../cppdll/cppdll.h"

void CCppTestDlg::OnBnClickedButton1()
{
    
switch(m_op)
    
{
    
case Add:
        
{            
            CString xStr;
            m_EditX.GetWindowText(xStr);
            CString yStr;
            m_EditY.GetWindowText(yStr);

            
double x = atof(xStr);
            
double y = atof(yStr);    
            
double sum =Math::Add(x, y); 
            

            CString sumStr;
            sumStr.Format(
"%f",sum);
            m_EditSum.SetWindowText(sumStr);
            
break;
        }

    
case Multiply:
        
{
            CString xStr;
            m_EditX.GetWindowText(xStr);
            CString yStr;
            m_EditY.GetWindowText(yStr);

            
double x = atof(xStr.GetBuffer());
            
double y = atof(yStr);    
            
double sum = Math::Multiply(x, y);

            CString sumStr;
            sumStr.Format(
"%f",sum);
            m_EditSum.SetWindowText(sumStr);
            
break;
        }

    
case Factorial:
        
{
            CString xStr;
            m_EditX.GetWindowText(xStr);            

            
double x = atoi(xStr);            
            
double sum = AdvancedMath::Factorial(x);

            CString sumStr;
            sumStr.Format(
"%f",sum);
            m_EditSum.SetWindowText(sumStr);
        
break;
        }

    
default:
        
break;
    }

}

3)CLI的wrapper
#pragma once

class Math;
class AdvancedMath;

namespace CppMathLib
{
public ref class MathWrapper
{
public:
    
static double Add(double x, double y);
    
    
static double Multiply(double x, double y);
    
}
;

public ref class AdvancedMathWrapper
{
public:
    
static int Factorial(int x);
}
;
}



#include 
"stdafx.h"
#include 
"MathWrapper.h"
#pragma comment(lib, 
"../debug/CppDLL.lib")
#include 
"../CppDLL/cppdll.h"

using namespace CppMathLib;

 
double MathWrapper::Add(double x, double y)
{
    
return Math::Add(x, y);
}

 
double MathWrapper::Multiply(double x, double y)
{
    
return Math::Multiply(x,y);
}


 
int AdvancedMathWrapper::Factorial(int x)
{
    
return AdvancedMath::Factorial(x);
}

4)C#的Form调用CLI的wrapper
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace CsharpTest
{
    
enum Operation
    
{
        Add,
        Multiply,
        Factorial,
        None
    }

    
public partial class Form1 : Form
    
{
        
private Operation op = Operation.None;

        
public Form1()
        
{
            InitializeComponent();     
        }


        
private void radioButtonMultiply_CheckedChanged(object sender, EventArgs e)
        
{
            op 
= Operation.Multiply;

            textBoxY.Enabled 
= true;
        }


        
private void radioButtonAdd_CheckedChanged(object sender, EventArgs e)
        
{
            op 
= Operation.Add;

            textBoxY.Enabled 
= true;
        }


        
private void radioButtonFactorial_CheckedChanged(object sender, EventArgs e)
        
{
            op 
= Operation.Factorial;

            textBoxY.Text 
= "0";
            textBoxY.Enabled 
= false;
        }


        
private void button1_Click(object sender, EventArgs e)
        
{           
           
switch(op)
           
{
               
case Operation.Add:
                   textBoxSum.Text 
= CppMathLib.MathWrapper.Add(Double.Parse(textBoxX.Text), Double.Parse(textBoxY.Text)).ToString();
                   
break;
               
case Operation.Multiply:
                   textBoxSum.Text 
= CppMathLib.MathWrapper.Multiply(Double.Parse(textBoxX.Text), Double.Parse(textBoxY.Text)).ToString();
                   
break;
               
case Operation.Factorial:
                   textBoxSum.Text 
= CppMathLib.AdvancedMathWrapper.Factorial(Int32.Parse(textBoxX.Text)).ToString();
                   
break;
               
default:
                   
break;
           }



        }


        
private void button2_Click(object sender, EventArgs e)
        
{
            
this.Close();
        }

    }

}

三 截图比较
     
 
     

     前面的是C++的MFC的dialog,后面的C#的Form,看起来一样哦,就是开发速度不同!


四 代码下载:http://www.cppblog.com/Files/mzty/CsharpCallCppByCLI.rar

posted on 2007-12-25 19:14 梦在天涯 阅读(6967) 评论(2)  编辑 收藏 引用 所属分类: CPlusPlusC#/.NETManage c++ /CLI

评论

# re: C#的Form通过CLI调用C++的DLL[未登录] 2008-09-26 10:06 笑笑生

请问:
对于DLL中的对象方法,需要实例化才可以使用,在这里该如何实现呢?  回复  更多评论   

# re: C#的Form通过CLI调用C++的DLL[未登录] 2015-07-30 19:34 jeffrey

错误 6 当前上下文中不存在名称“CppMathLib” C:\.......\Desktop\CsharpCallCppByCLI\CsharpTest\Form1.cs 54

请问是什么问题,亲手编译请教。多谢!
  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1625913
  • 排名 - 5

最新评论

阅读排行榜