问题描述
我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中:intretrieve(intscanno,void*buf);
在C中是通过先定义一个结构体再调用这个函数的:#defineCOUNT_DIMENSION_MAX256typedefstructtagVECTOR_st{intdimension;doublevector[COUNT_DIMENSION_MAX];}VECTOR_st;structtagSample_st{intID;VECTOR_stVec;//}rec;retrieveall(scanno,&rec);
请问各位大牛,这个retrieve函数的参数void*buf在C#中应该转换成什么?C#中并不能定义void*,我查找过一些资料,貌似说是转换成IntPtr,publicstaticexternintretrieveall(intscanno,IntPtrbuf);
但是在C#中调用的时候应该传递什么样的参数给buf呢?C#中又不能写成&rec这种形式。希望大家帮忙解答!谢谢各位!
解决方案
解决方案二:
如果是.net4可以使用dynamic类型再转换
解决方案三:
引用楼主的回复:
我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中:C/C++codeintretrieve(intscanno,void*buf);在C中是通过先定义一个结构体再调用这个函数的:C/C++code#defineCOUNT_DIMENSION_MAX256typedefstructtagVECTOR_s……
C#中的IntPtr类型称为“平台特定的整数类型”,它们用于本机资源,如窗口句柄。资源的大小取决于使用的硬件和操作系统,但其大小总是足以包含系统的指针(因此也可以包含资源的名称)。举个例子[DllImport("winmm.dll")]privatestaticexternlongmciSendString(stringa,stringb,uintc,IntPtrd);然后用这样的方法调用:mciSendString("setcdaudiodooropen",null,0,this.Handle);您也可以使用IntPtr.Zero将句柄设置为0;或者使用类型强制转换:mciSendString("setcdaudiodooropen",null,0,(IntPtr)0);或者,使用IntPtr构造函数:IntPtra=newIntPtr(2121);
解决方案四:
C和C++中的结构要转换到C#中,要在C#中重新定义这个C或者C++的结构,后通过指针转换到结构。
解决方案五:
引用3楼的回复:
C和C++中的结构要转换到C#中,要在C#中重新定义这个C或者C++的结构,后通过指针转换到结构。
我知道要在C#中重新定义结构了,关键在于我不知道intretrieve(intscanno,void*buf)这个函数在C#中怎么声明,因为C#没办法把函数的参数声明成void*buf
解决方案六:
引用4楼的回复:
引用3楼的回复:C和C++中的结构要转换到C#中,要在C#中重新定义这个C或者C++的结构,后通过指针转换到结构。我知道要在C#中重新定义结构了,关键在于我不知道intretrieve(intscanno,void*buf)这个函数在C#中怎么声明,因为C#没办法把函数的参数声明成void*buf
是应该用void*C#对应的就是IntPtr啊
解决方案七:
传结构体嘛。
解决方案八:
用IntPtr也是可以的,但这样需要自行申请和释放非托管内存建议的方法是定义为reftagSample_stbuffer,即使用引用传递tagSample_st结构,这相当于向C传递该tagSample_st结构的指针
解决方案九:
structtagSample_st{intID;VECTOR_stVec;//}rec;这不是个结构吗,你用类来写,试试传引用
解决方案十:
引用7楼的回复:
用IntPtr也是可以的,但这样需要自行申请和释放非托管内存建议的方法是定义为reftagSample_stbuffer,即使用引用传递tagSample_st结构,这相当于向C传递该tagSample_st结构的指针
由于这个函数intretrieve(intscanno,void*buf)是用于读取数据库中某一个表中某条记录的所有字段,而数据库中不同表拥有的字段也是不同的(那个struct结构体就是用来定义一个表中的每个字段的),所以并不能将参数声明成统一的结构体,只能声明成一个指针。那么如果只能用IntPtr的话,如何自行申请和释放非托管内存?
解决方案十一:
以tagSample_st为例:publicpartialclassLibWrap{constintCOUNT_DIMENSION_MAX=256;[StructLayout(LayoutKind.Sequential)]publicstructtagVECTOR_st{intdimension;[MarshalAs(UnmanagedType.ByValArray,SizeConst=COUNT_DIMENSION_MAX)]double[]vector;}[StructLayout(LayoutKind.Sequential)]publicstructtagSample_st{intID;tagVECTOR_stVec;}[DllImport("MyDll.dll")]publicstaticexternintretrieveall(intscanno,IntPtrbuf);}LibWrap.tagSample_strec=newLibWrap.tagSample_st();intcb=Marshal.SizeOf(typeof(LibWrap.tagSample_st));IntPtrptr=Marshal.AllocCoTaskMem(cb);//Marshal.StructureToPtr(rec,ptr,true);intiResult=LibWrap.retrieveall(0,ptr);Marshal.PtrToStructure(ptr,rec);Marshal.FreeCoTaskMem(ptr);
其实如果不同的表,对应不同的字段,定义不同的结构,也可以利用函数重载,使用ref