小弟正在做一个设备的接口开发,是用VB写的OCX,我用C#调用有一个方法调用一直不正确,请大师指导一下:
添加OCX引用后,其方法在C#中看到的定义如下:
GetAllData(string ip, ref int rowCount, ref string[] gra_Date, ref string[] gra_No);方法的作用是:从设备返回所有数据,rowCount是记录数,gra_Date是日期((应定义有 10 个元素的数组),gra_No是编号((应定义有 10 个元素的数组),厂家的技术支持提供了VB的DEMO,能正确返回结果,无C#的(问了说不懂C#,没办法,我们必须在C#中做)。该方法在C#中一直没成功返回结果。我查了一下网上的资料,好像说OCX是非托管代码,要进行封装什么的,不懂啊,这个问题已经折腾1个星期了,请各位大侠指教啊,不然要失业了。
谢谢!

解决方案 »

  1.   

    既然能添加COM引用,就已经可以调用了。你不是已经看到方法列表了么。你的调用代码是怎么写的呢?
      

  2.   

    以前曾经做过,应该不会有问题你把调用OCX的代码贴出来看看是不是OCX的调用路径没有写对?一定要指定到最终的目录
      

  3.   

    caozhy说的问题确实存在,小公司的技术保障很难实现长久。
      

  4.   

    理论上说,.NET可以完全向下兼容COM调用。但是,没有兼容性问题的软件,只停留在理论上
      

  5.   


    int count = 0;
    string[] gra_Date = new string[14];
    string[] gra_No = new string[14];int retVal = tbocx.GetAllData("192.168.0.100", ref count, ref gra_Date, ref gra_No);正确执行,retVal应该返回为0, 数据是保存在数组中的。
    我现在执行返回结果为负数。OCX的其它方法都调用正确,就只有这个方法的参数是数组,其它方法的参数都是简单类型。
      

  6.   

    我用DELPHI 6测试过这个方法,是可以调用成功的。DELPHI中看到的数组参数都是SafeArray类型,
    C#我是折腾了一个星期都没解决到。 
      

  7.   

    C#所使用的.Net FrameWork SDK都是受管代码,而对于那些COM组件来说,他们都是非受管代码(Unmanaged Code),所以这些COM组件要能够被VB.NET和C#使用,必须实现自身从非受管代码到受管代码的转换。在.Net框架中提供了一个程序来专门实现这种转换,这个文件就是"Aximp.exe",如果你把.Net FrameWork SDK安装在"C"盘,那么在"C:\Program Files\Microsoft.NET\FrameworkSDK\Bin"目录中,就可以找到这个文件。假设你的文件是tb.ocx运行:Aximp c:\tb.ocx运行上述命令后就可以实现转换,并在当前目录中产生"tb.dll"和"Axtb.dll"二个文件。添加引用Axtb.dll
      

  8.   

    直接引用就好了,VS会自动进行转换确定不是内部逻辑问题,或IP访问失败,???
      

  9.   


    这个已经做了,OCX的其它方法我都能正确调用
      

  10.   

    如果是SafeArray,你的函数签名是错的,应该是:
    GetAllData(string ip, ref int rowCount, ref object gra_Date, ref object gra_No);
    调用时:
    int count = 0;
    object gra_Date = new VariantWrapper("日期");
    object gra_No = new VariantWrapper("编号");
    int retVal = tbocx.GetAllData("192.168.0.100", ref count, ref gra_Date, ref gra_No);
      

  11.   


    你的函数签名是错的? 
    我在C#中添加OCX引用后,声明OCX对象后,它的方法的参数类型就是string[],不是object啊。
      

  12.   

    用TypeLib Viewer看下IDL中函数原型的定义是什么
    运行Visual Studio程序组下面Microsoft Windows SDK Tools -> OLE/COM Object View
    File->View TypeLib...
      

  13.   

    实在不行,就是用delphi再封装一次吧。
    c#在和ocx的交互上,数据类型确实是个很麻烦的东西。
      

  14.   

    你把ocx先添加到左边的工具栏选项卡里,再把它拖到Form的面板上!
    你在右边的引用栏,点击这个ocx,看看这个方法到底是不是你说的这样:
    GetAllData(string ip, ref int rowCount, ref string[] gra_Date, ref string[] gra_No);如果确实是这样,你把在C#中的代码贴出来看看。
      

  15.   


    通过添加控件的方法,在C#中看到这个方法的定义:
    GetAllData(string ip, ref int rowCount, ref Array gra_Date, ref Array gra_No);通过Aximp.exe生成DLL添加引用,看到的就是string[],而不是Array.提供的VB,DEMO,代码很简单,    
        Dim gra_count As Long                  
        Dim gra_Date(14) As String
        Dim gra_No(14) As String
        Me.OCX1.GetAllData(IP, Record_Num, gra_Date(), gra_No())
      

  16.   

    那你模仿VB的方式:int count=0;
    string[] gra_Date=new string[14]{""};
    int gra_No=0;
    string[] gra_No=new string[14]{""};int retVal = tbocx.GetAllData("192.168.0.100", ref count, ref gra_Date, ref gra_No);
      

  17.   

    你用 vb包装成一个类库给c#调用
      

  18.   

    他的参数是要一个String的引用, 或者准确点说是要一个byte数组,你却定义一个string数组,肯定出错了,你可以试下:
    byte[] tempbyte = new byte[50];
    int retVal = tbocx.GetAllData("192.168.0.100", ref count, tempbyte[0], tempno[0]);
      

  19.   

    关键是看你添加引用后, 他的函数声明式是如何的, 我想有可能就是ref string
      

  20.   

    这个就是找厂家要的OCX的VB源代码中的函数定义:
    Public Function GetAllData(ByVal IP As String, ByRef  RowCount As Long, 
                              ByRef GRA_Date() As String, ByRef GRA_No() As String) As Long我通过Aximp.exe生成DLL添加引用,看到的参数类型就是string[]。难道是Aximp.exe生成有误?
    GetAllData(string ip, ref int rowCount, ref string[] gra_Date, ref string[] gra_No);
      

  21.   

    要不把你的那个OCX放上来吧,大家可以一起看看,按他的函数声明, 就是一个string
      

  22.   

    这类似的问题我碰到过,我蛮同意TragicGuy的意见。你可以改为string 或是 ref byte【】试试。
    另外,你的疑问Aximp.exe生成有误时完全可能的。俺用BCB时IDE自带的工具生成的代码连头文件的声明都是错的,所有的注释被它当做代码。
      

  23.   

    工具栏中-选择项-COM组件,添加需要的OCX,然后直接像控件一样使用,另外要注意配置环境变量,刚做过一个加载C做的OCX,应该类似,希望有帮助~~~
      

  24.   

    如果要调用非托管代码 先通过DllImport导入dll,然后通过关键字extern使用 以前在做短信猫的时候使用过 不知道这个方法适不适合你
      

  25.   

    ----------------------------------
    int count = 0;
    string[] gra_Date = new string[14];
    string[] gra_No = new string[14];int retVal = tbocx.GetAllData("192.168.0.100", ref count, ref gra_Date, ref gra_No);正确执行,retVal应该返回为0, 数据是保存在数组中的。
    我现在执行返回结果为负数。OCX的其它方法都调用正确,就只有这个方法的参数是数组,其它方法的参数都是简单类型。
    ----------------------------------------------------------------------
        这里gra_Date和gra_No只是分配了制定数目的引用,而没有分配sring对象,我怀疑是不是这儿的代码问题。
    string[] gra_Date = new string[14];
    for (int i = 0; i < 14; ++i)
    {
        gra_Date[i] = new string();     
    }
    string[] gra_No = new string[14];
    for (int i = 0; i < 14; ++i)
    {
        gra_No[i] = new string();
    }
      

  26.   

    vb里面调用正确,而C#里面出错,
    VB是VS里自带的那个吗?