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

解决方案 »

  1.   

    calss ss = new class();
      

  2.   

    -_-不太明白,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行)说的我不太明白......
      

  3.   

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

  4.   

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

  5.   

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

  6.   

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

  7.   

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

  8.   

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

  9.   

    以下是我的dumpbin的部分结果:
    >dumpbin -exports ExpertSystem.dllDump of file ExpertSystem.dllFile 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 .text
      

  10.   

    这是我的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;
    };
      

  11.   

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

  12.   

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

  13.   

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

  14.   

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

  15.   

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

  16.   

    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#中很麻烦。
      

  17.   

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

  18.   

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

  19.   

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

  20.   

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

  21.   

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

  22.   

    以这个简单的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;
    }
    };
      

  23.   

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

  24.   

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

  25.   

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

  26.   

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

  27.   

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

  28.   

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