CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  C#

(关于.NET对旧程序的兼容的问题)c#中如何调用VC++6.0写的DLL?

楼主shiyubeijing()2006-05-01 16:26:08 在 .NET技术 / C# 提问

我已经有一个VC++6.0写的DLL,他实现了比较复杂的功能,其中有一个专家系统。现在想把它做成webService。我想把它封装成一个C#做的DLL这样在webService中就可以直接引用了。我知道可以用DllImport把函数引进来,但是Dll导出的是一个类,怎样把这个类引进来呢?应为类中的成员函数和变量都有用呀! 问题点数:30、回复次数:31Top

1 楼antiking(生活就象拉大便有时顺畅有时不顺畅.)回复于 2006-05-01 16:52:15 得分 0

calss   ss   =   new   class();Top

2 楼shiyubeijing()回复于 2006-05-01 21:05:51 得分 0

-_-不太明白,calss   ss   =   new   class();这个class从哪里来总得说明白吧!  
  如果是一个函数可以用如下方法把vc++的dll的导出函数fun1引入到c#中:  
  [DllImport("MyDll.dll",EntryPoint="fun1")]  
  public   static   extern   int   fun1(int   a,   int   b);  
  但是怎样才能把vc++写的dll的类导入呢?antiking(Q狼E行)说的我不太明白......Top

3 楼shiyubeijing()回复于 2006-05-01 22:58:24 得分 0

急切等待中。。。请高手指点!Top

4 楼Knight94(愚翁)回复于 2006-05-02 09:23:15 得分 20

如果你用DllImport是在C#类库的话,那么在webservice工程中直接添加引用即可使用。Top

5 楼shiyubeijing()回复于 2006-05-02 13:31:35 得分 0

Knight94(愚翁)你是不是说可以在webService工程中右键->添加引用?我用的式VS.NET2003,这时会弹出对话框,有三种类型可以被添加:.NET,com和项目。如果直接想把VC++6的DLL引入的话,VS弹出对话框说“这不是有效的.NET程序集,...请确保该文件可以被访问并且是有效的程序集或COM组件”!所以是不能在工程中直接对VC++6的DLL引用。不知愚翁的意思我理解对了没?Top

6 楼Knight94(愚翁)回复于 2006-05-02 13:52:24 得分 0

当然不是这个意思Top

7 楼Knight94(愚翁)回复于 2006-05-02 13:54:41 得分 0

不过你调用vc6的dll中以类返回,是有些麻烦Top

8 楼shiyubeijing()回复于 2006-05-02 20:44:10 得分 0

呵呵,连愚翁都这么说,看来真的不好弄了。。。  
  不知c#的平台调用是否就是==DllImport,是否只是引入非托管的函数而不能引入类,如果真的如此我就不能再看平台调用了。但是还有什么办法呢?  
  急呀!难道大家都没有遇到过或是考虑这样的问题吗?请大家给个法子呀!Top

9 楼Knight94(愚翁)回复于 2006-05-03 08:24:09 得分 0

你在vs环境下的dos去用dumpbin来输出你的dll,是否能看到dll输出的函数。  
   
  还有,你能把dll中的头文件贴一部分,让我看看。Top

10 楼soaringbird()回复于 2006-05-03 09:06:55 得分 10

以前曾经用空类的方式,在VC和Delphi之间共享过类,但这种方式在C#和VC之间行不行。Top

11 楼shiyubeijing()回复于 2006-05-03 15:38:13 得分 0

以下是我的dumpbin的部分结果:  
  >dumpbin   -exports   ExpertSystem.dll  
   
  Dump   of   file   ExpertSystem.dll  
   
  File   Type:   DLL  
   
      Section   contains   the   following   exports   for   ExpertSystem.dll  
   
          00000000   characteristics  
          44331D00   time   date   stamp   Wed   Apr   05   09:27:28   2006  
                  0.00   version  
                        1   ordinal   base  
                      25   number   of   functions  
                      25   number   of   names  
   
          ordinal   hint   RVA             name  
   
                      1         0   000011F9   ??0CExpert@@QAE@XZ  
                      2         1   00001221   ??1CExpert@@QAE@XZ  
                      3         2   00001294   ?AssertActionData@CExpert@@IAEXXZ  
                      4         3   0000128F   ?AssertInputData@CExpert@@IAEXXZ  
                      5         4   00001235   ?ChooseClipsName@CExpert@@QAEXVCString@@@Z  
                      6         5   0000101E   ?CommendWeapon@CExpert@@QAEXH@Z  
                      7         6   000010EB   ?Execute@CExpert@@QAEXXZ  
                      ......  
                      23       16   000011A4   ReportMemoryProblems  
                      24       17   00001244   capturePrint  
                      25       18   0000124E   captureQuery  
   
      Summary  
   
                  1000   .data  
                  1000   .idata  
                  2000   .rdata  
                  1000   .reloc  
                  1000   .rsrc  
                22000   .textTop

12 楼shiyubeijing()回复于 2006-05-03 15:45:17 得分 0

这是我的Dll的头文件的一部分,有删节:  
  #include   "Clipsmfc.h"  
   
  class   _declspec(dllexport)   CExpert  
  {  
  public:  
  void   CommendWeapon(int   target);  
  void   GetWarning(int   WarningID,float   Data);  
  void   ChooseClipsName(CString   ClipsName);  
  void   Execute();  
  struct   Result                                                                                                                
  {  
  char   name;  
  int   action;  
  int   target;  
  int   weapon;  
  int   method;  
  int   direction;  
  int   order;  
  };  
                    struct   Defense  
  {  
  int   type;  
  int   mode;  
  };  
  struct   Input  
  {  
  PlaneState   PlaneState_1;  
  PlaneState   PlaneState_2;  
  PlaneState   PlaneState_3;  
  PlaneState   PlaneState_4;  
  Defense         PlaneDefense;  
  };  
                      struct   Output  
  {  
  Result   Result_1;  
  Result   Result_2;  
  Result   Result_3;  
  Result   Result_4;  
  int   maneuver;  
  };  
  struct   Warning  
  {  
  int       Weather;                                    
  float   Wind_Direction;                      
  float   Horizontal_Wind_Speed;        
  float   Static_Temperature;              
  float   Static_Air_Pressure;            
  float   Electromagnetism_State;      
  float   Infrared_State;                      
  int       AlarmID;                                    
  float   GASM_1;                                      
  float   GASM_2;                                      
  float   GASM_3;                                      
  float   GASM_4;                                      
  };  
  struct   WarningOut  
  {  
  int   WarningID;  
  bool   Result;  
  };  
   
  struct   Weapon                                              
  {  
  int   target;                                          
  int   FirstWeapon;                                
  int   SecondWeapon;                              
  int   ThirdWeapon;                                
  };  
   
          Input   InputData;  
  Output   OutputData;  
  Warning   WarningData;  
  WarningOut   WarningOutData;  
  Weapon   WeaponCommended;  
   
  CExpert();  
  ~CExpert();  
           
   
  private:  
  CCLIPSWrap   *   m_pClips;  
  CStringArray   m_standard;  
  CStringArray   m_outNum;  
  CStringArray   m_outDef;  
  CStringArray   m_outAct;  
   
  protected:  
  void   ReadAction();  
                    ......  
  void   WarnWeather(int   Data);  
   
   
  BOOL   RunClips();  
  void   AssertInputData();  
  void   ReleaseClips();  
  BOOL   InitClips();  
  void   ReadResult();  
  CString   m_ClipsFileName;  
  };  
  Top

13 楼shiyubeijing()回复于 2006-05-03 15:53:16 得分 0

请看函数void   CommendWeapon(int   target);他的输入是一个int型的target变量;再看结构体struct   Weapon                                              
  {  
  int   target;                                          
  int   FirstWeapon;                                
  int   SecondWeapon;                              
  int   ThirdWeapon;                                
  };  
  在函数的具体实现中通过CommendWeapon这个函数就可以给出最后的结果保存在struct   Weapon中。CommendWeapon这个函数是没有返回值的,他的作用是得到一个类中的结构体。那如果仅仅用[DllImport(...)]引入这个函数而没办法得到结果即那个结构体是不行的呀。不知我说清楚了没有?Top

14 楼Knight94(愚翁)回复于 2006-05-03 18:53:21 得分 0

在dll中返回其定义的struct类型对象是没有什么问题,只要在c#中进行声明一个一样的struct,并进行序列化即可;但是所有的函数都是用类的成员函数输出,这是比较麻烦的。而且你的dll用dumpbin进行输出是乱码,这样通过dllimport是无法找到入口。  
   
  你可以用vc.net来引入要简单些。Top

15 楼shiyubeijing()回复于 2006-05-03 20:22:56 得分 0

哦,用“序列化”?!我再看看!  
   
  真的感谢Knight94(愚翁)   !谢谢!  
   
  另外我很想知道用VC++.NET真的会简单很多吗?那如果用VC++.NET会用到哪方面的知识呢?是不是C++托管还是C++/CLI?如果C#不是很复杂或是可能遇到更多的问题那我就继续弄下去了。  
   
  另外,虽然dumpbin是乱码,但是还是能一一对应的,如?CommendWeapon@CExpert@@QAEXH@Z就是CommendWeapon,dllImport时只要指定entrypoint=“?CommendWeapon@CExpert@@QAEXH@Z”还是可以找到入口点的(尽管可能笨了点或是不规范)。Top

16 楼shiyubeijing()回复于 2006-05-03 22:01:31 得分 0

序列化!!!看了一些序列化的东西,有点晕。。。  
  愚翁能否结合这个CommendWeapon函数和结构体Weapon给出个序列化的实例呢?这样方向明确一点。再次谢谢!Top

17 楼Knight94(愚翁)回复于 2006-05-04 08:32:20 得分 0

to   另外我很想知道用VC++.NET真的会简单很多吗?那如果用VC++.NET会用到哪方面的知识呢?是不是C++托管还是C++/CLI?如果C#不是很复杂或是可能遇到更多的问题那我就继续弄下去了。  
   
  因为你用vc.net调用dll要方便些,至少类似于指针方面的操作,要灵活多了。假如你如果dll的有.h以及.lib文件,就更方便了,直接在vc.net工程中引入.h,编译的时候加上.lib就可以了。  
  Top

18 楼Knight94(愚翁)回复于 2006-05-04 08:44:24 得分 0

to   能否结合这个CommendWeapon函数和结构体Weapon给出个序列化的实例呢?这样方向明确一点。再次谢谢!  
   
  [StructLayout(LayoutKind.Sequential)]  
  public   struct   Weapon  
  {  
          int   target;  
          int   FirstWeapon;  
          int   SecondWeapon;  
          int   ThirdWeapon;  
  }  
   
  那么如上的Weapon就可以在调用dll函数中进行使用了。  
   
  to   void   CommendWeapon(int   target)的调用  
  如果不是class的成员函数的话,那么调用非常简单,如下:  
  [DllImport(...)]  
  public   extern   static   void   CommendWeapon(   int   target   )  
  但是如果是类的成员函数的话,就比较麻烦了,要做的操作大致如下:  
  首先需要创建一个类的对象,然后找到函数table,再找到相应的函数项,最后再调用。  
   
  以上的操作在c#中很麻烦。Top

19 楼shiyubeijing()回复于 2006-05-04 09:37:47 得分 0

其实我是想把那个Dll实现的复杂功能弄成一个web服务,不管是C#还是vc++.net哪个方便用哪个。只是据我了解VC++.NET调用以前的dll需要用什么C++托管扩展,现在好像又新出了C++/CLI,好像也不简单。所以我才试着用C#。能轻松的把.h和.lib包含进去就能用Dll吗?如果真的那样我这么长时间就白弄了!Top

20 楼soaringbird()回复于 2006-05-04 09:53:47 得分 0

楼主,看到了你的消息,我是这么做的,比如以你的CExpert为例,在c++代码的dll代码中CExpert的定义,还应该有一个函数用以返回一个CExpert实例,比如CExpert   CreateExpert,这个函数要export出来供别的语言使用。在C#中也声明一个同样的CExpert类,但它的方法要写成纯虚的,同时把CExpert   CreateExpert函数import进来,就可以用CExpert   expert=CreateExpert(...)来创建CExpert的实例了,然后也可以调用其方法什么的。这种方式我在VC和Delphi之间用过,但VC和C#间能不能用就不太清楚了。Top

21 楼Knight94(愚翁)回复于 2006-05-04 09:56:14 得分 0

to   能轻松的把.h和.lib包含进去就能用Dll吗?  
   
  没问题Top

22 楼Knight94(愚翁)回复于 2006-05-04 10:07:02 得分 0

.lib与.dll,一个是静态的,一个是动态的,实现的功能都是一样的。Top

23 楼shiyubeijing()回复于 2006-05-05 15:24:28 得分 0

soaringbird()的方法给了我一些启发,不知对不对:  
          既然DllImport可以调用Dll里的函数,而要想把dll类中的成员变量引进来比较麻烦。那我可不可以在Dll中稍加改造:我创建一个静态的成员函数,这个成员函数可以创建dll类的实例并且返回这个实例,那我在C#里可以用DllImport引入这个创建实例的静态函数就行了!这样在C#里就有了Dll中的类的实例,这样调用方法和成员变量不就都行了吗?不知这样对吗?  
   
          还有一个关键问题就是在C#里必须写一个和Dll中的类一样的类!这个是必须的吧,但是该怎么写呢?以下面这个例子为例:Top

24 楼shiyubeijing()回复于 2006-05-05 15:26:16 得分 0

以这个简单的Dll的代码为例,在C#里应该怎样写那个虚拟的类呢?  
  class   _declspec(dllexport)   MyClass  
  {  
  private:  
  MyClass()  
  {  
  }  
  public:  
  static   MyClass   createInstance()  
  {  
  MyClass   a;  
  return   a;  
  }  
   
  public:  
  int   result;  
  void   add(int   a,   int   b)  
  {  
  result   =   a   +   b;  
  }  
  };  
  Top

25 楼Knight94(愚翁)回复于 2006-05-05 15:35:21 得分 0

不是我打击你,即使用静态成员函数,你在dumpbin中看到也是乱码,也就是说,你用dllimport很难找到entrypoint。Top

26 楼Knight94(愚翁)回复于 2006-05-05 15:38:31 得分 0

要么你把dll输出函数和dll类分开,那么在c#中只调用dll输出函数来模拟类的成员函数操作。  
  要么你用vc.net去引入.h和.lib做成类库供c#调用。Top

27 楼soaringbird()回复于 2006-05-05 17:00:55 得分 0

我正在给你试呢,Delphi调用VC的类是可以的,但C#下的可能不行,有托管代码和原生代码的差别。Top

28 楼soaringbird()回复于 2006-05-05 17:08:33 得分 0

其实你也不必非得在C#里直接调用vc的dll,也可以用VC把那个dll再封装一下,做成COM组件,在C#下就可以直接用了。Top

29 楼doitnow2000(大海)回复于 2006-05-07 10:20:20 得分 0

我现在准备用第三方开发包,第三方开发包是用vc写的,但是我想在C#用使用,结果引用的时候出错了,出现:这不是有效的.NET程序集,...请确保该文件可以被访问并且是有效的程序集或COM组件”  
  怎么办?Top

30 楼shiyubeijing()回复于 2006-05-07 19:18:31 得分 0

呵呵,doitnow2000(大海)可能和我遇到了类似的问题,就是在.NET下使用原来旧的程序的问题。   在c#里时不能随便引用VC下的程序的,必须做点工作,我这个菜鸟现在就是在搞这个问题。soaringbird()   说把dll再次封装一下,成COM组件我觉的也可以,我试试。Top

31 楼bufan2162(永远保持前进状态)回复于 2006-05-07 20:42:04 得分 0

顶,学习Top

相关问题

关键词

得分解答快速导航

  • 帖主:shiyubeijing
  • Knight94
  • soaringbird

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo