关于C#调用OCX的方法,传递数组参数的问题
小弟正在做一个设备的接口开发,是用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个星期了,请各位大侠指教啊,不然要失业了。
谢谢!
--------------------编程问答-------------------- 既然能添加COM引用,就已经可以调用了。你不是已经看到方法列表了么。
你的调用代码是怎么写的呢? --------------------编程问答-------------------- 一个连C#都不懂的厂商,他的产品你也敢用?遇到问题你找谁支持去?招聘一个C#程序员也不贵,这个厂商连这个钱都出不起。 --------------------编程问答-------------------- 以前曾经做过,应该不会有问题
你把调用OCX的代码贴出来
看看是不是OCX的调用路径没有写对?一定要指定到最终的目录 --------------------编程问答-------------------- 最关键的是,你用了这种作坊的东西,底下有得扯皮呢。你说是它设备的故障,他说是你调用不正确。你说我调给你看,他说我不懂C#。好吧,你们就扯去吧。 --------------------编程问答-------------------- caozhy说的问题确实存在,小公司的技术保障很难实现长久。
--------------------编程问答-------------------- 理论上说,.NET可以完全向下兼容COM调用。但是,没有兼容性问题的软件,只停留在理论上。 --------------------编程问答--------------------
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的其它方法都调用正确,就只有这个方法的参数是数组,其它方法的参数都是简单类型。
--------------------编程问答-------------------- 我用DELPHI 6测试过这个方法,是可以调用成功的。DELPHI中看到的数组参数都是SafeArray类型,
C#我是折腾了一个星期都没解决到。 --------------------编程问答-------------------- 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 --------------------编程问答-------------------- 不是应定义10个元素么?为什么定义为14?
另外,能返回负数,说明你能调用。 --------------------编程问答-------------------- 直接引用就好了,VS会自动进行转换
确定不是内部逻辑问题,或IP访问失败,???
--------------------编程问答--------------------
这个已经做了,OCX的其它方法我都能正确调用 --------------------编程问答--------------------
可以确定不是IP的问题,其它方法是可以正确调用的,
问题应该是出在托管与非托管上,请了解的大侠支招啊 --------------------编程问答-------------------- 帮顶,也关心这个问题 --------------------编程问答--------------------
是14位,输入错误,返回负数就是说明中间的参数传递不正确。 --------------------编程问答-------------------- 如果是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);
--------------------编程问答--------------------
你的函数签名是错的?
我在C#中添加OCX引用后,声明OCX对象后,它的方法的参数类型就是string[],不是object啊。 --------------------编程问答-------------------- 那就是底层的问题了。VB的示例呢? --------------------编程问答-------------------- 用TypeLib Viewer看下IDL中函数原型的定义是什么
运行Visual Studio程序组下面Microsoft Windows SDK Tools -> OLE/COM Object View
File->View TypeLib... --------------------编程问答-------------------- 实在不行,就是用delphi再封装一次吧。
c#在和ocx的交互上,数据类型确实是个很麻烦的东西。
--------------------编程问答-------------------- 你把ocx先添加到左边的工具栏选项卡里,再把它拖到Form的面板上!
你在右边的引用栏,点击这个ocx,看看这个方法到底是不是你说的这样:
GetAllData(string ip, ref int rowCount, ref string[] gra_Date, ref string[] gra_No);
如果确实是这样,你把在C#中的代码贴出来看看。。。。
--------------------编程问答--------------------
通过添加控件的方法,在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()) --------------------编程问答-------------------- 那你模仿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);
--------------------编程问答-------------------- 你用 vb包装成一个类库给c#调用 --------------------编程问答-------------------- 他的参数是要一个String的引用, 或者准确点说是要一个byte数组,你却定义一个string数组,肯定出错了,你可以试下:
byte[] tempbyte = new byte[50];
int retVal = tbocx.GetAllData("192.168.0.100", ref count, tempbyte[0], tempno[0]);
--------------------编程问答-------------------- 关键是看你添加引用后, 他的函数声明式是如何的, 我想有可能就是ref string --------------------编程问答-------------------- 这个就是找厂家要的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);
--------------------编程问答-------------------- 要不把你的那个OCX放上来吧,大家可以一起看看,按他的函数声明, 就是一个string --------------------编程问答-------------------- 这类似的问题我碰到过,我蛮同意TragicGuy的意见。你可以改为string 或是 ref byte【】试试。
另外,你的疑问Aximp.exe生成有误时完全可能的。俺用BCB时IDE自带的工具生成的代码连头文件的声明都是错的,所有的注释被它当做代码。 --------------------编程问答-------------------- 路过 帮顶 --------------------编程问答-------------------- weiguan,kankan,xuexixia --------------------编程问答--------------------
笑话,谁规定设备厂商一定要懂C#? --------------------编程问答-------------------- 工具栏中-选择项-COM组件,添加需要的OCX,然后直接像控件一样使用,另外要注意配置环境变量,刚做过一个加载C做的OCX,应该类似,希望有帮助~~~ --------------------编程问答-------------------- 如果要调用非托管代码 先通过DllImport导入dll,然后通过关键字extern使用 以前在做易做图的时候使用过 不知道这个方法适不适合你 --------------------编程问答-------------------- ----------------------------------
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();
}
--------------------编程问答-------------------- 帮顶!!! --------------------编程问答-------------------- vb里面调用正确,而C#里面出错,
VB是VS里自带的那个吗?
补充:.NET技术 , C#