C++ Programmer's Cookbook

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

一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用


 一 引子

      1)使用VS2005,Native C++,C#,CLI/C++。
      2)主要介绍CLI/C++和Native C++, C#的交互,最总能够实现以CLI/C++为中介的Native C++与C#的互调。

 二 实例
      
      1)实现一个CLI/C++的Dll,在此Dll中包含一个RefClass能够被C#的exe调用。(实现过程:在VS中建立C++ CLR Class library 的一个Project,然后增加一个类RefClass)代码如下:

      refclass.h文件:
      
#pragma once 

namespace ClrCppDll 
{
    
public ref class RefClass
    
{
    
public:
        RefClass()
{}
        RefClass(
int _x, int _y) : x(_x), y(_y)
        
{
        }

        
void PrintSelf();
    
    
private:
        
int x;
        
int y;
    }
;
}

      refclass.cpp文件:
#include "stdafx.h"
#include 
"refclass.h"

using namespace System;
using namespace ClrCppDll;

void RefClass::PrintSelf()
{
    System::Console::WriteLine(
"hello, i am a ref cpp class");
    System::Console::WriteLine(
"x is {0}",x);
    System::Console::WriteLine(
"y is {0}",y);
}

      2)能够调用上面第1)步中的CLI/C++的Dll中class的C#的exe。(实现过程:在VS建立C#的console Application,然后reference 前面的1)生成的Dll)代码如下:

         Program.cs文件:
using System;
using System.Collections.Generic;
using System.Text;

namespace CsharpTest
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            ClrCppDll.RefClass refClass 
= new ClrCppDll.RefClass(2,4);
            refClass.PrintSelf();
        }

    }

}

            上面2步的代码下载http://www.cppblog.com/Files/mzty/CSharpCPPCLI1.rar (实现CLI/C++的dll能够被C#调用)



     3)对1)实现的CLI/C++的Dll中增加能够被Native C++调用的NativeClass。代码如下:

      NativeClass.h文件:
#pragma once

namespace ClrCppDll
{
    
public class NativeClass
    
{        
        
public:
            NativeClass()
{}
            NativeClass(
int _x, int _y) : x(_x), y(_y)
            
{}

            
void printSelf();

        
private:
            
int x;
            
int y;    
    }
;
}

      NativeClass.cpp文件:
#include "stdafx.h"
#include 
<iostream>
#include 
"nativeclass.h"

using namespace ClrCppDll;

void NativeClass::printSelf()
{
    std::cout
<<"hello,i am a native cpp class!"<<std::endl;
    std::cout
<<"x is "<<x<<std::endl;
    std::cout
<<"y is "<<y<<std::endl;                
}


      问题: 如果我们直接在NativeC++的exe调用上面CLI/C++中的NativeClass,会有问题,Error 1 error C3381: 'CppClrDll::NativeClass' : assembly access specifiers are only available in code compiled with a /clr option d:\cppandcsharpinteractivetest\csharpcppcli\clrcppdll\nativeclass.h 8,这是为什么那,我们想想我们一般的Native C++的DLL的调用,都要将要被调用的Class或funtion导出才可以调用,想到这里我们也对我们的NativeClass进行导出。(怎么导出可以看下面的代码)但是当增加了对NativeClass的导出,调用的时候仍然有上面的error,Error 1 error C3381: 'CppClrDll::NativeClass' : assembly access specifiers are only available in code compiled with a /clr option d:\cppandcsharpinteractivetest\csharpcppcli\clrcppdll\nativeclass.h 9,最后只有查找资料(没有找到)问别人(没有问到),最后想到使用导出函数试试,一试果然可行啊,哈哈哈,so Happy其实后来发现是我加的导出__declspec(dllexport)的位置不对,应该是在class关键字后面,总之导出类也是可以的。导出类的代码可以下载新的sample,增加导出和导出的函数代码如下:

      (导出不久需要下面的2文件,还的定义宏 CLR_CPP_DLL在编译选项中,或直接写在文件中)
      clrcppdll.h
// ClrCppDll.h

#pragma once

#ifdef CLR_CPP_DLL
#define DLLIMPEXP __declspec(dllexport)
#else
#define DLLIMPEXP
#endif

namespace ClrCppDll 
{
    DLLIMPEXP 
void  CallNativeClassPrintSelf();    
}

      clrcppdll.cpp文件:
// This is the main DLL file.

#include 
"stdafx.h"
#include 
"NativeClass.h"
#include 
"ClrCppDll.h"

DLLIMPEXP 
void  ClrCppDll::CallNativeClassPrintSelf()
{
    ClrCppDll::NativeClass test(
10,20);
    test.printSelf();
}

      4)建立一个NativeC++的exe来调用1)生成的CLI/C++的Dll中的3)增加的NativeClass(实现过程:建立一个Native C++的console application)代码如下:

       cpptest.cpp文件:(经过上一步问题的反复折磨,终于搞定)(同时别忘了要在编译选项中指定lib和lib的路径)
// CppTest.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"
#include 
"../ClrCppDll/clrcppdll.h"

int _tmain(int argc, _TCHAR* argv[])
{
    
/*ClrCppDll::NativeClass test(5,6);
    test.PrintSelf();
*/


    ClrCppDll::CallNativeClassPrintSelf();
    
return 0;
}


   上面四步总代码下载:http://www.cppblog.com/Files/mzty/CSharpCPPCLI2.rar (实现CLI/C++的dll同时被Native C++和C#的调用)

      5)扩展,增加在NativeClass中调用RefClass的funtion, 和RefClass中调用NativeClass的function。

      代码下载:http://www.cppblog.com/Files/mzty/CSharpCPPCLI3.rar (最后代码下载,包含NativeClass与RefClass的互调)
                           http://www.cppblog.com/Files/mzty/CSharpCPPCLI32.zip (包含native class的导出也调用)


      三 总结

      1) CLI/C++中如果想导出让NativeC++使用,则最好导出函数,也可以导出类。
      2) CLI/C++的DLL可以没有像一般的NativeC++的Dll中的DllMain()函数。
      3) CLI/C++如果想导出让C#使用,则一般是ref class。







posted on 2007-12-20 22:47 梦在天涯 阅读(8600) 评论(7)  编辑 收藏 引用 所属分类: CPlusPlusC#/.NETManage c++ /CLI

评论

# re: 一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用 2007-12-21 08:59 <a href=http://minidx.com>minidxer</a>

不错不错~很有用  回复  更多评论   

# re: 一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用 2007-12-22 09:19 GIS大魔鬼

c++/cli比其他.net语言的强大之处在于托管与非托管代码的混合开发。

NativeClass。__declspec(dllexport)dll导出是传统的标准win32 dll接口,在native代码中可以用隐式调用或用win32 api 的loadlibrary显示调用。
RefClass是一个的CLS类,所有.net语言都可以直接调用

楼主最后一个例子事实上就是本地代码与托管代码对混合程序集的调用
  回复  更多评论   

# re: 一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用 2008-05-19 17:48 qjrong

CLI/C++中如果想导出让NativeC++使用,则最好导出函数,也可以导出类。

请问怎么导出函数和类  回复  更多评论   

# re: 一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用 2008-05-20 08:40 梦在天涯

@楼上,还是一样的方法啊,用dllexport  回复  更多评论   

# re: 一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用 2009-05-19 14:04 我不清楚是谁

这样的代码还是要在有.net 的平台上运行?  回复  更多评论   

# re: 一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用 2011-10-12 16:55 zouwei

谢谢楼主哈  回复  更多评论   

# re: 一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用 2013-10-17 15:29 hzexe

clr的可以生成lib库给NativeC++调用?  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


公告

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

搜索

  •  

积分与排名

  • 积分 - 1796879
  • 排名 - 5

最新评论

阅读排行榜